Document targeted recovery and retain scheduler diagnostics

This commit is contained in:
evgeny committed 2026-10-25 16:26:14 +01:00
1 parent 46f6c03147
commit 288b8091ce
3 files changed
+8 -18

No files matched your search

+4 -2
View File
@@ -1,6 +1,8 @@
/*
* chat_sync — связь чат-сервиса с транспортом и группами.
* Отслеживает пиров, запускает member_sync, поддерживает кеш каналов и статус в GUI.
* UP/REINIT/пробуждение восстанавливают только общие каналы соответствующего пира.
* Отложенные запросы объединяются по (канал, пир); активными обменами и обновлениями владеет Merkle.
* Вход по ссылке держит отдельный NCD handle до результата join, а не только до UP.
* JOIN_INFO_REQ → JOIN_INFO_RESP → JOIN_REQUEST → JOIN_READY; правила — в chat_join.h.
* Жизненным циклом управляет chat_service_start/stop. Вызовы — в потоке uasync,
@@ -101,8 +103,8 @@ void chat_sync_join_channel(struct UTUN_INSTANCE* inst, const char* ch_id, uint6
Вызывается из auto_socket при появлении/изменении сетевой связности. */
void chat_sync_retry_channels_on_socket_change(struct UTUN_INSTANCE* inst);
/* Немедленно убрать канал из кеша chat_sync (локальное удаление канала),
* чтобы cs_on_conn_status не запускал member_sync для удалённого ns до следующего refresh. */
/* Отменить отложенные запросы канала и немедленно убрать его из кеша (локальное удаление).
* Активные Merkle-сессии отменяет вызывающий код через member_sync_cancel_channel(). */
void chat_sync_on_channel_deleted(struct UTUN_INSTANCE* inst, const char* ch_id);
/* Разослать всем подключённым пирам канала смену per-chat настройки «play sound on message». */
+2 -15
View File
@@ -343,12 +343,8 @@ static void ms_work(void* arg) {
s->work = NULL;
if (s->state != MS_IDLE || !s->dirty || s->tx) return;
int rc;
if (s->leader) {
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "merkle local work: dataset=%u ns=%s peer=%016llx revision=%llu verified=%llu",
s->dataset->id, s->ns, (unsigned long long)s->peer,
(unsigned long long)s->revision, (unsigned long long)s->verified_revision);
rc = ms_begin(s);
} else { s->dirty = 0; rc = ms_send(s, MS_WAKE, 0, NULL, 0); }
if (s->leader) rc = ms_begin(s);
else { s->dirty = 0; rc = ms_send(s, MS_WAKE, 0, NULL, 0); }
if (rc < 0) ms_fail(s, MT_ERR_IO, "start send", 1);
}
@@ -358,8 +354,6 @@ void merkle_sync_changed(struct UTUN_INSTANCE* inst, uint8_t dataset, const char
for (struct ms_session* s = ms->sessions; s; s = s->next) {
if (s->dataset->id != dataset || strcmp(s->ns, ns)) continue;
s->revision++; s->dirty = 1;
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "merkle changed: dataset=%u ns=%s peer=%016llx state=%d revision=%llu",
dataset, ns, (unsigned long long)s->peer, s->state, (unsigned long long)s->revision);
if (s->state == MS_FAILED) { s->state = MS_IDLE; s->previous_valid = 0; }
if (s->state == MS_IDLE && ms_schedule(s) < 0) {
ms_fail(s, MT_ERR_IO, "change scheduling", 1); return;
@@ -506,10 +500,6 @@ static void ms_receive(struct ETCP_CONN* conn, struct ll_entry* entry) {
/* Follower мог отменить и заново подключить namespace. Старый запрос уже некому обслужить. */
ms_discard_tx(s);
s->previous_valid = 0;
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG,
"merkle remote wake: dataset=%u ns=%s peer=%016llx state=%d dirty=%d revision=%llu verified=%llu",
dataset, ns, (unsigned long long)s->peer, s->state, s->dirty,
(unsigned long long)s->revision, (unsigned long long)s->verified_revision);
rc = ms_begin(s);
}
} else if (type == MS_BEGIN) {
@@ -667,9 +657,6 @@ int merkle_sync_start(struct UTUN_INSTANCE* inst, uint8_t dataset, uint64_t peer
u_free(r); return -1;
}
if (s->state == MS_FAILED) { s->state = MS_IDLE; s->previous_valid = 0; }
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG,
"merkle start request: dataset=%u ns=%s peer=%016llx state=%d dirty=%d revision=%llu callback=%d",
dataset, ns, (unsigned long long)peer, s->state, s->dirty, (unsigned long long)s->revision, cb != NULL);
s->dirty = 1;
if (s->state == MS_IDLE && ms_schedule(s) < 0) {
u_free(r); ms_fail(s, MT_ERR_IO, "start scheduling", 1); return -1;
+2 -1
View File
@@ -71,7 +71,7 @@ static void setup(struct fixture* f) {
for (struct ll_entry* e = f->inst->topo_groups->group_list->head; e; e = e->next) {
struct TOPO_GROUP* group = (struct TOPO_GROUP*)e;
assert(group->group_type == TOPO_GROUP_TYPE_CHAT && channels < 2);
snprintf(f->channel[channels], sizeof(f->channel[channels]), "%s", group->channel_id);
snprintf(f->channel[channels], sizeof(f->channel[channels]), "%llu", (unsigned long long)group->group_id);
f->gid[channels++] = group->group_id;
}
assert(channels == 2);
@@ -80,6 +80,7 @@ static void setup(struct fixture* f) {
struct ETCP_CONN* conn = etcp_connection_create(f->inst, "schedule peer"); assert(conn);
conn->peer_node_id = sc_derive_node_id_from_pubkey(keys.public_key);
conn->initialized = 1; conn->links_up = 1; conn->state = 1;
assert(sc_init_ctx(&conn->crypto_ctx, &f->inst->my_keys) == SC_OK);
assert(sc_set_peer_public_key(&conn->crypto_ctx, keys.public_key, SC_PEER_PUBKEY_BIN) == SC_OK);
assert(etcp_conn_index_peer(conn) == 0); f->peers[i] = conn;
uint8_t signature[64] = {0};