Document media attempt validation and reserve before tracking outgoing writes

This commit is contained in:
evgeny committed 2026-10-22 19:33:12 +02:00
1 parent 99389f4bd3
commit c81cc8b9ca
2 files changed
+16 -8

No files matched your search

+4 -5
View File
@@ -426,11 +426,6 @@ void chat_core_submit_media_message(struct UTUN_INSTANCE* inst, struct chat_msg_
return;
}
/* build media_base from db_path: dirname(db_path) e.g. /path/to/data */
if (media_index_track_preparation(cc->db, req->channel_id, destination, media_base)) {
chat_event_submitted(inst, req->request_id, 0); return;
}
/* copy fields for async callback (req is freed by trampoline immediately) */
struct media_submit_ctx* mctx = u_calloc(1, sizeof(*mctx));
if (!mctx) {
@@ -439,6 +434,10 @@ void chat_core_submit_media_message(struct UTUN_INSTANCE* inst, struct chat_msg_
}
mctx->destination = media_delivery_reserve(inst, destination);
if (!mctx->destination) { u_free(mctx); chat_event_submitted(inst, req->request_id, 0); return; }
if (media_index_track_preparation(cc->db, req->channel_id, destination, media_base)) {
media_delivery_release(inst, mctx->destination); u_free(mctx);
chat_event_submitted(inst, req->request_id, 0); return;
}
mctx->inst = inst;
mctx->request_id = req->request_id;
mctx->next = cc->media_submissions; cc->media_submissions = mctx;
+12 -3
View File
@@ -5,6 +5,9 @@
* QUERY: одна пачка до 32 блоков в полёте, отдельный UUID/дедлайн, источники только своей группы и автор.
* До четырёх кандидатов на блок; до десяти используемых узлов, слоты переиспользуются после освобождения.
* Повторы ограничены источниками и бюджетом провалов блока; OVERLOADED соблюдает retry_after.
* Попытка имеет UUID и отдельный temp; принимается только непрерывный префикс от текущего узла своей группы.
* Прогресс обновляется после успешного close; DONE проверяет размер и подпись по сохранённому ключу автора.
* Проверенный temp независимо удерживают relay-выдачи. Итоговый файл публикуется после полного SHA-256.
* done сообщает результат, а не гарантирует доставку другим участникам. */
#ifndef MEDIA_DOWNLOAD_H
#define MEDIA_DOWNLOAD_H
@@ -72,7 +75,6 @@ struct media_download_peer {
/* ── внутреннее состояние загрузки (доступно для тестов) ── */
struct media_download {
struct ll_entry ll;
struct ll_entry* entry; /* Владеющая запись; после удаления из индекса живёт до последнего refs. */
unsigned refs; /* Активная загрузка и обработчики, вызывающие пользовательские callbacks. */
struct media_destination* destination; // Исключительное право записи dest_path до terminal.
@@ -112,11 +114,13 @@ struct media_download {
struct UTUN_INSTANCE* inst;
};
/* Запустить непустой файл с корректной геометрией и массивами block_ids/block_sigs.
/* Запустить непустой файл с корректной геометрией и массивами block_ids/block_sigs; блок до MEDIA_BLOCK_SIZE_MAX.
* author_node_id должен иметь ровно 32 байта Ed25519-ключа в nodes; значение первого байта не используется как признак наличия.
* dest_path <1024, media_base <512 байт (UTF-8); назначение принадлежит общей базе БД, смена базы отклоняется.
* Проверки идут до создания каталогов. 0 — принят: done_cb ровно один раз, в том числе синхронно при отсутствии суперузлов;
* -1 — отказ без done_cb, включая уже активный media_id. Аргументы callbacks заимствованы до done_cb.
* Успех включает атомарную регистрацию блоков собранного файла. Ошибка регистрации не удаляет собранный файл;
* Успех включает атомарную регистрацию блоков опубликованного файла в SQLite; общей транзакции ФС/БД нет.
* Ошибка регистрации не удаляет опубликованный файл;
* путь остаётся в media_preparations для удаления канала. Остальные поля result копируются до возврата.
* progress_cb может отменить загрузку и запустить новую с тем же media_id; done_cb старой загрузки
* вызывается после возврата из progress_cb, когда её последний обработчик освободил контекст. */
@@ -127,6 +131,8 @@ int media_download_start(struct UTUN_INSTANCE* inst, uint64_t group_id,
void (*done_cb)(void* arg, int err), void* done_arg,
void (*progress_cb)(void* arg, int blocks_done, int num_blocks), void* progress_arg);
/* Отменить всю загрузку media_id: block_id/chunk не используются. Отдельный CANCEL отправляется для каждой текущей попытки.
* 0 — отменена, -1 — не найдена. done_cb(-2) после последнего удерживающего обработчика; повторной отмены/done нет. */
int media_download_cancel(struct UTUN_INSTANCE* inst,
const uint8_t* media_id, const uint8_t* block_id, uint32_t chunk);
@@ -136,6 +142,9 @@ int media_download_cancel(struct UTUN_INSTANCE* inst,
* Может завершить загрузку и вызвать done_cb; после возврата прежний dl может быть освобождён. */
void media_download_handle_query_resp(struct UTUN_INSTANCE* inst,
uint64_t group_id, uint64_t from_node, const uint8_t* data, size_t len);
/* group_id/from_node берутся из router. Длина/состояние/блок/chunk/UUID проверяются до записи и прогресса.
* Повреждение текущей попытки меняет держателя, локальная ошибка завершает загрузку.
* Чужие и устаревшие пакеты игнорируются; обработчики могут завершить загрузку синхронно. */
void media_download_handle_chunk(struct UTUN_INSTANCE* inst,
uint64_t group_id, uint64_t from_node, const uint8_t* data, size_t len);
void media_download_handle_done(struct UTUN_INSTANCE* inst,