diff --git a/doc/service_lifecycle.md b/doc/service_lifecycle.md index bba6d4c3..ae94ce4f 100644 --- a/doc/service_lifecycle.md +++ b/doc/service_lifecycle.md @@ -46,6 +46,27 @@ SQLite открывается ядром один раз: `db_path/chats.db`, л на общих соединениях. Транзит других групп сохраняется. Отложенный LEAVE может временно удерживать транспорт самостоятельно, не обращаясь к уже удалённой группе. +ETCP удаляет транспорт после 30 секунд непрерывного DOWN, независимо от NCD handles. +Первоначальное ожидание UP тоже ограничено этим сроком. Повторный DOWN не продлевает +таймаут; восстановление UP отменяет его. Владельцы получают CLOSED, внешние ссылки +задерживают только освобождение памяти. Освобождение последнего handle во время DOWN +оставляет транспорт до его таймаута; явный force-close и отмена неудачной попытки закрывают сразу. + +Входящий UP без локальных handles сохраняется: он может быть нужен пиру. CLOSE/KEEP_ALIVE +привязан при запуске ядра, поэтому мягкое закрытие работает и на чисто входящем узле. +На CLOSE при наличии handles отвечаем KEEP_ALIVE; без них закрываем транспорт. +KEEP_ALIVE полностью отменяет FIN_WAIT. Ожидание CLOSE обычно занимает 5 секунд, +для спящего пира увеличивается до его RX deadline. Сам факт DOWN во время FIN_WAIT +завершает ранее запрошенное мягкое закрытие. + +Контроль RX независим от отправки keepalive. Объявленный сон не отключает проверку +жизни: срок от последнего RX равен максимуму согласованного keepalive timeout и +объявленного остатка ACTIVE+SLEEP с запасом normal timeout. Фазовые таймеры и наши +отправки срок жизни пира не продлевают. После истечения последнего линка транспорт +становится DOWN, затем удаляется через 30 секунд. `test_etcp_server_lifecycle` +проверяет сроки, несколько путей, восстановление, владение, сон и CLOSE/KEEP_ALIVE +с управляемыми часами и контролем освобождения памяти/таймеров. + Остановка чата сначала прекращает внешние команды и фоновые задания, затем закрывает медиа и сервисы, синхронизацию и группы, после чего освобождает chat core. `media_async_destroy()` дожидается завершения native workers и вызывает каждый diff --git a/src/transport_layer/etcp.c b/src/transport_layer/etcp.c index 2cff8e40..b2a3fd9e 100644 --- a/src/transport_layer/etcp.c +++ b/src/transport_layer/etcp.c @@ -1112,8 +1112,9 @@ void etcp_on_link_down(struct ETCP_CONN* etcp, struct ETCP_LINK* down_link) { } int was_up = etcp->links_up; etcp->links_up = up; - if (!up && etcp_down_timer_start(etcp) < 0) { etcp_connection_close(etcp); return; } - else etcp_down_timer_cancel(etcp); + if (!up) { + if (etcp_down_timer_start(etcp) < 0) { etcp_connection_close(etcp); return; } + } else etcp_down_timer_cancel(etcp); if (up == 0 && was_up != 0) { DEBUG_INFO(DEBUG_CATEGORY_ETCP, "All links fall down"); etcp_on_down(etcp, down_link);