From 16a5e628fd57bcf7c0ac9723ab655ee2d69cd797 Mon Sep 17 00:00:00 2001 From: evgeny Date: Thu, 22 Oct 2026 14:46:15 +0200 Subject: [PATCH] Report incomplete media cleanup separately from channel deletion --- src/chat/chat_channel.c | 26 +++++++++----------------- src/chat/chat_core.h | 5 ++++- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/chat/chat_channel.c b/src/chat/chat_channel.c index 6afa1c94..34fd6e27 100644 --- a/src/chat/chat_channel.c +++ b/src/chat/chat_channel.c @@ -319,20 +319,6 @@ void chat_core_apply_group_autoconnect(struct UTUN_INSTANCE* inst) { /* ─── локальное удаление канала ─── */ -static const char* cc_ui_state_get(struct chat_core_ctx* cc, const char* key) { - static char val[512]; - val[0] = '\0'; - sqlite3_stmt* st = NULL; - if (sqlite3_prepare_v2(cc->db, "SELECT value FROM ui_state WHERE key=?", -1, &st, NULL) == SQLITE_OK) { - sqlite3_bind_text(st, 1, key, -1, SQLITE_STATIC); - if (sqlite3_step(st) == SQLITE_ROW) { - const char* v = (const char*)sqlite3_column_text(st, 0); - if (v) snprintf(val, sizeof(val), "%s", v); - } - sqlite3_finalize(st); - } - return val; -} void chat_core_delete_channel(struct UTUN_INSTANCE* inst, const char* ch_id) { struct chat_core_ctx* cc = CC(inst); @@ -341,6 +327,7 @@ void chat_core_delete_channel(struct UTUN_INSTANCE* inst, const char* ch_id) { return; } if (!ch_id || !ch_id[0]) { DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "%s: delete_channel — empty ch_id", CC_ID); return; } + if (chat_media_defer_channel_delete(inst, ch_id)) return; DEBUG_INFO(DEBUG_CATEGORY_CHAT_SYNC, "%s: delete_channel BEGIN ch=%s", CC_ID, ch_id); uint64_t gid = strtoull(ch_id, NULL, 10); @@ -368,10 +355,14 @@ void chat_core_delete_channel(struct UTUN_INSTANCE* inst, const char* ch_id) { chat_sync_on_channel_deleted(inst, ch_id); /* 6. удалить медиафайлы канала на диске + строки media_files */ - media_index_delete_channel(cc->db, ch_id, cc_ui_state_get(cc, "media_base")); + char media_base[MEDIA_BASE_MAX]; + int media_error = media_index_get_base(cc->db, media_base) || media_index_delete_channel(cc->db, ch_id, media_base); + if (media_error) DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "channel=%s removed with incomplete media cleanup; retry required", ch_id); /* 7. удалить таблицы и метаданные канала */ - topo_node_sqlite_channel_delete(cc->db, ch_id); + if (topo_node_sqlite_channel_delete(cc->db, ch_id)) { + DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "channel metadata deletion failed ch=%s", ch_id); return; + } /* 8. уведомить GUI */ { @@ -380,7 +371,8 @@ void chat_core_delete_channel(struct UTUN_INSTANCE* inst, const char* ch_id) { chat_event_post(inst, CHAT_EVT_CHANNEL_DELETED, evt, 1 + cl); } - DEBUG_INFO(DEBUG_CATEGORY_CHAT_SYNC, "%s: delete_channel DONE ch=%s gid=0x%016llx", CC_ID, ch_id, (unsigned long long)gid); + DEBUG_INFO(DEBUG_CATEGORY_CHAT_SYNC, "%s: delete_channel DONE ch=%s gid=0x%016llx media_cleanup=%s", + CC_ID, ch_id, (unsigned long long)gid, media_error ? "incomplete" : "complete"); } void chat_core_delete_channel_trampoline(void* arg) { diff --git a/src/chat/chat_core.h b/src/chat/chat_core.h index d6d01b32..fa96adb1 100644 --- a/src/chat/chat_core.h +++ b/src/chat/chat_core.h @@ -147,7 +147,10 @@ struct chat_delete_channel_req { /* Удалить канал с этого устройства: отмена медиа-загрузок, удаление группы * (соединения/синк), db_sync инстанса, таблиц msg_ и peers_, медиафайлов и - * merkle-хешей. Работает в uasync-потоке. Другие узлы канал не теряют. */ + * merkle-хешей. Работает в uasync-потоке. Другие узлы канал не теряют. + * Исходящие video/register задачи сначала завершаются; удаление продолжит последний completion. + * Новые исходящие медиа этого канала в это время отклоняются. Событие CHANNEL_DELETED приходит после удаления метаданных; + * ошибка файловой очистки логируется отдельно, записи неочищенных файлов сохраняются для повтора. */ void chat_core_delete_channel(struct UTUN_INSTANCE* inst, const char* ch_id); void chat_core_delete_channel_trampoline(void* arg);