Verify outgoing request persistence and document commit boundary
This commit is contained in:
1 parent
d1bfd1d16c
commit
851c6723ff
3 files changed
+76
-1
No files matched your search
@@ -909,3 +909,39 @@ utun_node,редактирование/удаление/события/отве
|
||||
создания запроса,файловых completion,удаления и восстановления;отметки[~] сохранены.
|
||||
По новой инструкции пользователя дефекты исправляются и проверяются по мере аудита,
|
||||
с последующим обновлением текстов,без остановки на обнаружении дефекта.
|
||||
|
||||
Исходящий REQUEST — 27.10.2026, runtime d1bfd1d1
|
||||
|
||||
Подтверждён пропуск вставки attachment_key_requests при SQLITE_DONE/changes0:
|
||||
RAISE(IGNORE) оставляет outbox REQUEST без запроса,после чего прежний таймер
|
||||
сообщает об успехе. Новый постоянный тест до runtime-правки завершился ожидаемым
|
||||
assert:reader в событии показал request0/state-1/command1/autocommit1.
|
||||
Полный короткий лог:/tmp/attachment-outgoing-negative.log,исходная libutun не менялась.
|
||||
|
||||
ak_request_file теперь владеет BEGIN IMMEDIATE/COMMIT,под блокировкой перечитывает
|
||||
downloaded/wanted/ready/decrypting/error/key и отсутствие прежнего запроса.
|
||||
Проверяет все prepare/bind/step/changes1/finalize запроса и общей ak_queue,затем
|
||||
commit;только после него идут событие и отправка. Общий rollback сохраняет прежние
|
||||
строки. Сам tick откладывает файлы и outbox при внешней транзакции без её изменения.
|
||||
Если rollback потребовал quiesce/stop,tick больше не вызывает pump и не ставит таймер.
|
||||
Чтение выбранного файла проверяет размеры identity/key,указатели,пути и finalize.
|
||||
Wire/схема/API не менялись. Ошибки содержат этап/код/канал/автора,успех — committed.
|
||||
|
||||
test_attachment_requests дополнен52 SQL-отказами с успешным повтором и дубликатом:
|
||||
пустая/существующая очередь,BEGIN/COMMIT,pending/eligibility read,insert request,
|
||||
outbox,каждый prepare/bind/step/finalize и число изменённых строк.
|
||||
Дополнительно ABORT/IGNORE запроса/INSERT/UPDATE outbox,настоящий commit veto,
|
||||
сохранность внешней транзакции до создания и при уже готовой к отправке очереди,
|
||||
rollback fault с проверкой stop/unbind/отсутствия таймера и откатом при destroy.
|
||||
Readonly reader проверяет обе строки перед событием и REQUEST,соседний ключ не меняется.
|
||||
Нет маршрута/backpressure/send fault→настоящий restart→запрос,очередь и дата сохранены;
|
||||
init сбрасывает retry_at,следующий проход повторяет REQUEST без нового события/запроса.
|
||||
Расширенный тест PASS,баланс выделений восстановлен:/tmp/attachment-outgoing-unit.log.
|
||||
Первичный native-профиль requests/decisions/results/chat_attachment/encrypted_attachment5/5
|
||||
PASS:/tmp/attachment-outgoing-profile.log и /tmp/attachment-outgoing-profile-logs.
|
||||
Санитайзеры и общая итоговая проверка продолжаются;полный аудит attachment остаётся[~].
|
||||
|
||||
Перед этой правкой upstream4d87cab2 объединён merge8a0654e5:изменения Android-жестов
|
||||
и документация DM сохранены без конфликтов;native runtime в upstream не менялся.
|
||||
После merge Android assembleDebug PASS:/tmp/attachment-request-fix-merge-android-build.log.
|
||||
Merge и проверенный REQUEST fix отправлены в origin обычным push8a0654e5.
|
||||
@@ -110,6 +110,15 @@ instance того же процесса остаются защищены общ
|
||||
создаёт; ручная пользовательская загрузка на таком узле запрашивает доступ.
|
||||
Сетевая классификация `peers.storage` для этого не используется.
|
||||
|
||||
Таймер создаёт исходящий REQUEST собственной BEGIN IMMEDIATE/COMMIT: повторно
|
||||
проверяет, что файл скачан и нужен, ключ отсутствует и прежнего запроса нет;
|
||||
затем сохраняет ровно один исходящий запрос и команду outbox. Все SQL-этапы,
|
||||
число строк и commit проверяются. Уведомление и отправка следуют после commit.
|
||||
Отказ сохраняет прежние строки, следующий проход повторяет подготовку.
|
||||
При внешней транзакции весь проход файлов и отправки откладывается, не меняя её.
|
||||
Если rollback не закрыл собственную транзакцию, таймер не запускается повторно:
|
||||
модуль снимается и владелец останавливает ядро после poll.
|
||||
|
||||
В шапке desktop-клиента кнопка «Запросы расшифровки» видна при наличии запросов без решения
|
||||
и показывает их число.
|
||||
Список содержит участника, вложение, дату и отдельные кнопки выдачи/отказа.
|
||||
@@ -209,6 +218,11 @@ backpressure и повтором через 5 секунд; restart продол
|
||||
внешняя транзакция, неверные состояние/направление/идентичность/флаги/мембер,
|
||||
потеря ACK из-за маршрута/backpressure/send failure и повтор с прежней датой,
|
||||
отказ rollback с остановкой и закрытием БД владельцем.
|
||||
Тот же тест проверяет52 SQL-отказа создания исходящего REQUEST с пустой/существующей
|
||||
outbox, ABORT/IGNORE, commit veto, внешнюю транзакцию до создания и до отправки,
|
||||
отсутствие повторного события/запроса, rollback fault без повторного таймера.
|
||||
Readonly reader видит обе строки до события и перед REQUEST; при отсутствии маршрута,
|
||||
backpressure и ошибке send настоящий restart сохраняет очередь и исходную дату запроса.
|
||||
|
||||
`test_attachment_decisions` проверяет116 SQL-отказов/повторов выдачи и отказа, с пустой
|
||||
и существующей очередью: чтение подписанного мембера, допуск автора, запись состояния,
|
||||
|
||||
@@ -482,11 +482,36 @@ static void test_outgoing_rollback_failure(void) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_MEDIA, "PASS outgoing requests: rollback failure stops core without event/send or rearming timer");
|
||||
}
|
||||
|
||||
static void test_outgoing_restart(void) {
|
||||
struct fixture f; setup(&f);
|
||||
for (int unavailable = 0; unavailable < 3; unavailable++) {
|
||||
outgoing_reset(&f, 0);
|
||||
if (!unavailable) f.route_up = 0;
|
||||
else if (unavailable == 1) f.room = 0;
|
||||
else f.send_rc = -1;
|
||||
outgoing_tick(&f, 1, unavailable == 2);
|
||||
struct snapshot saved = snapshot(&f);
|
||||
chat_event_set_handler(f.inst, NULL); active = NULL; utun_instance_destroy(f.inst);
|
||||
char config[1024];
|
||||
snprintf(config, sizeof(config), "[global]\ndb_path=%s\n[ntp]\nenabled=no\n"
|
||||
"[chatserver]\ngroup_autoconnect=0\nstorage_autoload=0\n", f.directory);
|
||||
f.inst = utun_instance_create_from_str(f.ua, config);
|
||||
assert(f.inst && !utun_core_start(f.inst) && !chat_service_start(f.inst));
|
||||
f.route.inst = f.inst; f.route_up = f.room = 1; f.send_rc = 0; active = &f;
|
||||
chat_event_set_handler(f.inst, event);
|
||||
struct snapshot restored = snapshot(&f);
|
||||
assert(restored.exists && restored.incoming == 0 && restored.state == 0 && restored.command == 1 && restored.retry == 0);
|
||||
assert(restored.created == saved.created); outgoing_tick(&f, 0, 1);
|
||||
}
|
||||
cleanup(&f);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_MEDIA, "PASS outgoing requests: no route/backpressure/send error preserve queue and date across real instance restart");
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
debug_config_init(); debug_set_level(DEBUG_LEVEL_ERROR); debug_set_category_level(DEBUG_CATEGORY_MEDIA, DEBUG_LEVEL_INFO);
|
||||
utun_instance_set_tun_init_enabled(0); size_t baseline = u_get_allocated_count();
|
||||
if (argc != 2 || strcmp(argv[1], "--outgoing")) { test_faults(); test_controls(); test_ack_retry(); test_rollback_failure(); }
|
||||
test_outgoing_controls(); test_outgoing_faults(); test_outgoing_rollback_failure();
|
||||
test_outgoing_controls(); test_outgoing_faults(); test_outgoing_restart(); test_outgoing_rollback_failure();
|
||||
assert(!fault && !fail_rollback && u_get_allocated_count() == baseline);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_MEDIA, "PASS attachment requests: reader before ACK/events, stable duplicate date, neighboring key and allocations preserved");
|
||||
return 0;
|
||||
|
||||
Reference in new issue
Block a user