docs(member-files): complete public request and transfer contracts

This commit is contained in:
evgeny committed 2026-10-24 18:47:06 +02:00
1 parent c1da55ad87
commit 4f96926f6b
3 files changed
+27 -10

No files matched your search

+23 -8
View File
@@ -17,7 +17,8 @@ typedef void (*mf_response_fn)(void* arg, const struct mf_message* response);
// ── Жизненный цикл модуля ──
// Создать состояние сервера/клиента и запустить дисковый worker; 0/-1.
// Создать состояние сервера/клиента и worker; 0/-1. Требует живые ua/config/router/chat/SQLite, повторный init — ошибка.
// Стартовый scan асинхронный: init=0 ещё не означает готовность локального storage; remote client остаётся доступен.
int member_files_init(struct UTUN_INSTANCE* inst);
// Запретить новые команды и начать отмену запросов/передач; запущенный дисковый I/O завершается отдельно.
@@ -26,7 +27,7 @@ void member_files_quiesce(struct UTUN_INSTANCE* inst);
// Дождаться дискового worker и освободить контекст; вне callbacks, до удаления CHAT-групп.
void member_files_destroy(struct UTUN_INSTANCE* inst);
// Отменить запросы и передачи одной группы перед её удалением.
// Отменить свои запросы/передачи одной группы перед её удалением; дерево storage этим не удаляется.
void member_files_cancel_group(struct UTUN_INSTANCE* inst, uint64_t group);
// ── Команды файлового сервера ──
@@ -39,6 +40,7 @@ struct mf_pending* member_files_request(struct UTUN_INSTANCE* inst, uint64_t gro
const struct mf_message* request, mf_response_fn callback, void* arg);
// Синхронно завершить свой запрос ответом MF_CANCELLED; handle после вызова недействителен, NULL допустим.
// Это отмена локального ожидания; уже запущенная серверная мутация не откатывается.
void member_files_cancel(struct mf_pending* pending);
// Отменить pending-запрос с этим request_id; не отменяет потоковую передачу файла.
@@ -46,14 +48,20 @@ void member_files_cancel_request_id(struct UTUN_INSTANCE* inst, uint64_t id);
// ── Проверка доступа ──
// 1 — действующий мембер; storage!=0 дополнительно требует подписанную роль хранителя.
// 1 — полная source=0/deleted=0 запись мембера в локальной CHAT-таблице, иначе0.
// storage!=0 требует adm_tags.storage=yes и сохранённую64-байтную подпись; peers.storage не даёт полномочий.
int member_files_member(struct UTUN_INSTANCE* inst, uint64_t group, uint64_t node, int storage);
// ── Команда интерфейса ──
struct mf_gui_request { struct UTUN_INSTANCE* inst; uint64_t group, server; struct mf_message message; };
struct mf_gui_request {
struct UTUN_INSTANCE* inst; // Заимствованное ядро до ответа.
uint64_t group, server; // CHAT-группа и явно выбранный storage, в том числе self.
struct mf_message message; // Команда; для корреляции GUI выбирает ненулевой request_id.
};
// arg — u_malloc/u_calloc mf_gui_request; освобождается после ответа CHAT_EVT_MEMBER_FILES_RESPONSE.
// arg — u_malloc/u_calloc mf_gui_request; владение переходит при вызове trampoline, освобождается после ответа.
// CHAT_EVT_MEMBER_FILES_RESPONSE: group:8LE/server:8LE, затем mf_encode(response). Отказ запуска даёт ACCESS_DENIED.
void member_files_gui_request(void* arg);
// ── Потоковая передача файлов ──
@@ -65,12 +73,17 @@ struct mf_transfer_request {
// download: по ответу STAT, до открытия локального temp и передачи данных.
uint64_t max_bytes;
int upload; // ненулевой — загрузить local на сервер, 0 — скачать remote
uint8_t version[16]; // версия из STAT; нули при создании нового серверного файла
uint8_t version[16]; // Upload:ожидаемая версия/нули для создания; download:ожидаемая версия/нули для текущей.
char remote[MF_PATH_MAX + 1], local[MF_PATH_MAX + 1]; // путь в каталоге owner и локальный путь приложения
};
struct mf_transfer;
struct mf_transfer_progress { uint64_t id, done, total; uint16_t status; uint8_t finished; };
struct mf_transfer_progress {
uint64_t id; // Фактический ID handle, включая автоматически выбранный.
uint64_t done, total; // Upload:принятые router байты; download:записанные на диск, до финального sync/publish.
uint16_t status; // mf_status; результат окончательный только при finished.
uint8_t finished; // 0 progress (может отсутствовать),1 ровно одно завершение.
};
typedef void (*mf_transfer_fn)(void* arg, const struct mf_transfer_progress* progress);
// Один handle на файл; до 16 клиентских передач одновременно, включая upload/download к одному пиру.
@@ -79,6 +92,8 @@ typedef void (*mf_transfer_fn)(void* arg, const struct mf_transfer_progress* pro
// Прогресс заимствован на время callback. Cancel асинхронно ждёт свой I/O и не затрагивает другие handles.
// Request копируется; исходную структуру можно освободить сразу, arg должен жить до finished.
// Download заменяет local только после проверки/закрытия своего temp; отказ/отмена до создания не удаляет чужой temp.
// Совпадение строк local двух download запрещено; aliases/подмену локальных файлов исключает caller.
// Upload требует стабильный regular source; изменение снимка даёт STALE. Пустой файл допустим.
struct mf_transfer* member_files_transfer_start(const struct mf_transfer_request* request, mf_transfer_fn callback, void* arg);
// Запросить отмену своей передачи; завершение приходит через finished после закрытия её файлового I/O.
@@ -91,7 +106,7 @@ void member_files_transfer_cancel(struct mf_transfer* transfer);
* state=1 progress, 2 finished. arg — u_malloc/u_calloc mf_transfer_request, освобождается после finished. */
void member_files_gui_transfer(void* arg);
struct mf_cancel_request { struct UTUN_INSTANCE* inst; uint64_t id; };
struct mf_cancel_request { struct UTUN_INSTANCE* inst; uint64_t id; }; // Заимствованное ядро и фактический ID команды/передачи.
// arg — u_malloc/u_calloc mf_cancel_request, освобождается здесь; отменяет передачу либо одиночный запрос по id.
void member_files_gui_cancel(void* arg);
+2 -1
View File
@@ -73,7 +73,8 @@ void mf_put64(uint8_t* p, uint64_t value);
/* 1 — все n байт нулевые, иначе0. */
int mf_zero(const uint8_t* p, size_t n);
/* 1/0: строгий UTF-8, путь<=1024 байт, до60 компонентов по1..255 байт; root_allowed разрешает пустую строку.
* Отвергает leading '.', trailing '.'/' ', ASCII C0/DEL, Windows device names и \\: *?"<>| (без разрешения пробела после двоеточия). */
* Отвергает leading '.', trailing '.'/' ', ASCII C0/DEL и Windows device names.
* Запрещены обратная косая черта, двоеточие, '*', '?', '"', '<', '>', '|'. */
int mf_path_valid(const char* path, int root_allowed);
/* Записать wire: длина>0 либо-1 при переполнении; выход не меняется при отказе длины.
* Проверяет размеры, но не семантику command/ID/path. message/wire обязательны и не перекрываются. */
+2 -1
View File
@@ -21,10 +21,11 @@ void mf_worker_unreserve(struct mf_work* work);
/* До64 обычных задач, включая ожидающие done. При отказе done(-1) синхронно, work не вызывается. */
void mf_worker_submit(struct mf_worker* worker, mf_work_fn work, void* data, mf_done_fn done, void* arg);
/* Передать резерв worker без проверки лимита64: только обязательные cleanup continuations.
* После вызова резерв нельзя освобождать/использовать повторно. FIFO, done ровно один раз. */
* После вызова резерв нельзя освобождать/использовать повторно. Work выполняется FIFO, done ровно один раз. */
void mf_worker_submit_reserved(struct mf_worker* worker, struct mf_work* reserved,
mf_work_fn work, void* data, mf_done_fn done, void* arg);
// После quiesce владельца, вне callbacks: дождаться работ и их cleanup continuations, не останавливая pthread.
// Не запускает uasync рекурсивно; порядок done при drain не обещается. NULL допустим.
void mf_worker_drain(struct mf_worker* worker);
/* Drain, затем join и освобождение. Работы не прерываются и получают обычный done(0); NULL допустим. */
void mf_worker_destroy(struct mf_worker* worker);