From 52d8ec4e497a081468de5fe51f7d0c10cb3bc4f4 Mon Sep 17 00:00:00 2001 From: evgeny Date: Tue, 27 Oct 2026 03:12:37 +0100 Subject: [PATCH] Preserve attachment files when shutdown sees an open transaction --- src/chat/chat_attachment.c | 10 +++++++++- src/chat/chat_attachment.h | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/chat/chat_attachment.c b/src/chat/chat_attachment.c index c2293b9d..a5694649 100644 --- a/src/chat/chat_attachment.c +++ b/src/chat/chat_attachment.c @@ -1349,6 +1349,9 @@ static void ak_recover_temps(struct UTUN_INSTANCE* inst) { /* После crash/отмены убрать только собственные подготовки, не имеющие сообщения. * Вызывается до запуска workers либо после их полного завершения. */ static void ak_recover_preparations(struct UTUN_INSTANCE* inst) { + if (!sqlite3_get_autocommit(CC(inst)->db)) { + DEBUG_WARN(DEBUG_CATEGORY_MEDIA, "attachment keys: preparation recovery deferred while transaction is open; files preserved"); return; + } ak_recover_temps(inst); char base[MEDIA_BASE_MAX]; if (media_index_get_base(CC(inst)->db, base)) return; @@ -1392,7 +1395,12 @@ static void ak_recover_preparations(struct UTUN_INSTANCE* inst) { /* Отдельные локальные таблицы никогда не регистрируются в db_sync/Merkle. */ int chat_attachment_init(struct UTUN_INSTANCE* inst) { - if (!CC(inst) || !inst->media_async) { DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "attachment keys: invalid initialization"); return -1; } + if (!inst || !CC(inst) || !inst->media_async) { + DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "attachment keys: invalid initialization"); return -1; + } + if (!sqlite3_get_autocommit(CC(inst)->db)) { + DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "attachment keys: initialization rejected inside external transaction"); return -1; + } if (ak_exec(inst, "CREATE TABLE IF NOT EXISTS attachment_keys(" "channel TEXT NOT NULL,crypto_id BLOB NOT NULL CHECK(length(crypto_id)=16),message_id BLOB,author INTEGER NOT NULL," "key BLOB CHECK(key IS NULL OR length(key)=32),cipher_hash BLOB,cipher_path TEXT NOT NULL,plain_path TEXT NOT NULL," diff --git a/src/chat/chat_attachment.h b/src/chat/chat_attachment.h index bc9ed86c..277c4f29 100644 --- a/src/chat/chat_attachment.h +++ b/src/chat/chat_attachment.h @@ -28,13 +28,13 @@ struct UTUN_INSTANCE; // ── Жизненный цикл модуля ── -// Подключить таблицы, router-сервис и обработку сохранённых задач; 0/-1. +// Подключить таблицы, router-сервис и обработку сохранённых задач; 0/-1. Внешняя транзакция запрещена. int chat_attachment_init(struct UTUN_INSTANCE* inst); // Запретить новые подготовки и остановить таймер; запущенные workers завершаются отдельно. void chat_attachment_quiesce(struct UTUN_INSTANCE* inst); -// После завершения workers убрать незавершённые подготовки и отключить router-сервис. +// После workers убрать незавершённые подготовки; открытая транзакция откладывает recovery, сохраняя файлы. void chat_attachment_destroy(struct UTUN_INSTANCE* inst); // ── Отправка и учёт вложений ──