Browse Source

Recheck expired down lifetime when the last NCD owner releases it

master
evgeny 12 hours ago
parent
commit
fdaa20977d
  1. 4
      src/transport_layer/node_conn_direct.c
  2. 28
      tests/test_etcp_server_lifecycle.c

4
src/transport_layer/node_conn_direct.c

@ -1155,7 +1155,9 @@ static void ncd_handle_close(struct NODE_CONN_DIRECT* h, int force) {
if (!conn->links_up) {
DEBUG_INFO(DEBUG_CATEGORY_NCD, "[ncd] last handle released while DOWN, retaining until ETCP timeout node=%016llx",
(unsigned long long)entry->node_id);
ncd_finish(entry, 0); return;
ncd_finish(entry, 0);
if (etcp_conn_schedule_down_close(conn) < 0) etcp_connection_close(conn);
return;
}
if (entry->connect_timer) { uasync_cancel_timeout(entry->ua, entry->connect_timer); entry->connect_timer = NULL; }
conn->fin_wait = 1; conn->fin_wait_clear_cb = ncd_fin_wait_cancelled; conn->fin_wait_clear_arg = entry;

28
tests/test_etcp_server_lifecycle.c

@ -115,7 +115,7 @@ static void check_reconnect(void) {
teardown(); DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "PASS multiple links, reconnect cancellation and fresh DOWN deadline");
}
/* Локальный handle не препятствует удалению; release внутри DOWN сохраняет таймаут. */
/* Локальные handles защищают DOWN; release последнего учитывает уже прошедший срок. */
static void check_owner(int release) {
setup(); struct ETCP_CONN* conn = ready_conn(0); struct NODE_CONN_DIRECT* handle = NULL;
CHECK(node_conn_direct_open(&inst, 42, owner_cb, NULL, &handle, NULL) == NCD_REUSED);
@ -123,11 +123,32 @@ static void check_owner(int release) {
conn->links->link_status = 0; etcp_on_link_down(conn, conn->links);
CHECK(down == 1 && !deleted && conn->down_timer && !conn->close_requested);
test_clock_run_for(inst.ua, ETCP_DOWN_TIMEOUT_TB + 10000);
CHECK(deleted == 1 && closed == (release ? 0 : 1) && !inst.connections->count);
if (!release) node_conn_direct_close(handle);
if (!release) {
CHECK(!deleted && !closed && !conn->down_timer && conn->down_deadline_tb && inst.connections->count == 1);
CHECK(node_conn_direct_handle_count(conn) == 1);
struct NODE_CONN_DIRECT* second = NULL;
CHECK(node_conn_direct_open(&inst, 42, owner_cb, NULL, &second, NULL) == NCD_REUSED);
CHECK(node_conn_direct_handle_count(conn) == 2);
node_conn_direct_close(handle); CHECK(node_conn_direct_handle_count(conn) == 1 && !conn->close_requested);
node_conn_direct_close(second); test_clock_run_for(inst.ua, 10);
}
CHECK(deleted == 1 && !closed && !inst.connections->count);
teardown(); DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "PASS DOWN timeout with local owner release_on_down=%d", release);
}
/* Закрытие handle до deadline не начинает новые 30 секунд ожидания. */
static void check_release_before_deadline(void) {
setup(); struct ETCP_CONN* conn = ready_conn(0); struct NODE_CONN_DIRECT* handle = NULL;
CHECK(node_conn_direct_open(&inst, 42, NULL, NULL, &handle, NULL) == NCD_REUSED);
conn->links->link_status = 0; etcp_on_link_down(conn, conn->links);
uint64_t deadline = conn->down_deadline_tb;
test_clock_run_for(inst.ua, 100000); node_conn_direct_close(handle);
CHECK(!deleted && node_conn_direct_handle_count(conn) == 0 && conn->down_deadline_tb == deadline);
test_clock_run_for(inst.ua, 100000); CHECK(!deleted);
test_clock_run_for(inst.ua, 110000); CHECK(deleted == 1 && !inst.connections->count);
teardown(); DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "PASS last handle release preserves original DOWN deadline");
}
/* RX продлевает watchdog, затем молчание даёт DOWN и ещё 30 секунд до DELETE. */
static void check_silent_peer(int tcp) {
setup(); struct ETCP_CONN* conn = ready_conn(tcp); struct ETCP_LINK* link = conn->links;
@ -214,6 +235,7 @@ int main(void) {
check_reconnect(); CHECK(u_get_allocated_count() == baseline);
check_owner(0); CHECK(u_get_allocated_count() == baseline);
check_owner(1); CHECK(u_get_allocated_count() == baseline);
check_release_before_deadline(); CHECK(u_get_allocated_count() == baseline);
check_silent_peer(0); CHECK(u_get_allocated_count() == baseline);
check_silent_peer(1); CHECK(u_get_allocated_count() == baseline);
check_sleep(); CHECK(u_get_allocated_count() == baseline);

Loading…
Cancel
Save