Propagate media schema and downloaded registration failures

This commit is contained in:
evgeny committed 2026-10-22 14:42:44 +02:00
1 parent 113f0259ea
commit 8cba8ef3e6
2 files changed
+31 -42

No files matched your search

+9 -9
View File
@@ -107,6 +107,11 @@ int chat_core_init(struct UTUN_INSTANCE* inst, const char* db_path) {
if (!cc->shared_db) sqlite3_close(cc->db);
inst->chat_core = NULL; u_free(cc); return -1;
}
if (strlen(db_path) >= sizeof(cc->db_path) || media_index_init(cc->db)) {
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "chat media schema/path initialization failed");
if (!cc->shared_db) sqlite3_close(cc->db);
inst->chat_core = NULL; u_free(cc); return -1;
}
cc->inst = inst;
cc->my_node_id = inst->node_id;
@@ -141,9 +146,6 @@ int chat_core_init(struct UTUN_INSTANCE* inst, const char* db_path) {
/* register adm_tags change callback → CHAT_EVT_MEMBER_UPDATED */
chat_member_init(inst);
/* create media_files table */
media_index_init(cc->db);
db_exec(cc,
"CREATE TABLE IF NOT EXISTS local_identity ("
" id INTEGER PRIMARY KEY CHECK (id = 1),"
@@ -172,13 +174,11 @@ int chat_core_init(struct UTUN_INSTANCE* inst, const char* db_path) {
);
/* store media_base for block_req handler */
{
char mbase[512];
char mbase[MEDIA_BASE_MAX];
const char* ls = strrchr(db_path, '/');
if (ls) snprintf(mbase, sizeof(mbase), "%.*s", (int)(ls - db_path), db_path);
else snprintf(mbase, sizeof(mbase), "%s", db_path);
char sql[1024]; snprintf(sql, sizeof(sql),
"INSERT OR REPLACE INTO ui_state(key,value) VALUES('media_base','%s')", mbase);
sqlite3_exec(cc->db, sql, NULL, NULL, NULL);
if (ls) snprintf(mbase, sizeof(mbase), "%.*s", ls == db_path ? 1 : (int)(ls - db_path), db_path);
else snprintf(mbase, sizeof(mbase), ".");
if (media_index_set_base(cc->db, mbase)) { chat_core_destroy(inst); return -1; }
DEBUG_INFO(DEBUG_CATEGORY_CHAT_SYNC, "%s: media_base=%s", CC_ID, mbase);
}
+22 -33
View File
@@ -639,30 +639,19 @@ void media_download_handle_chunk(struct UTUN_INSTANCE* inst,
/* Регистрирует скачанные блоки в media_files (location = собранный файл), чтобы узел
* мог отдавать их как держатель. Вызывается после успешной сборки и проверки хеша. */
static void md_dl_register_servable(struct media_download* dl) {
static int md_dl_register_servable(struct media_download* dl) {
struct UTUN_INSTANCE* inst = dl->inst;
sqlite3* db = inst ? inst->topo_sqlite_db : NULL;
if (!db) { DEBUG_WARN(DEBUG_CATEGORY_GENERAL, "%s: register_servable — no DB", MDL_ID); return; }
char chat_id[32];
snprintf(chat_id, sizeof(chat_id), "%llu", (unsigned long long)dl->group_id);
/* location = dest_path относительно media_base (как в media_index_commit) */
const char* rel = dl->dest_path;
size_t base_len = strlen(dl->media_base);
if (strncmp(rel, dl->media_base, base_len) == 0 && rel[base_len] == '/')
rel += base_len + 1;
for (int n = 0; n < dl->num_blocks; n++) {
if (media_index_register_downloaded(db, dl->media_id, dl->blocks[n].block_id,
dl->content_hash, chat_id, rel, inst->node_id,
dl->file_size, dl->blocks[n].expected_size, n,
(int64_t)n * dl->block_size) != 0) {
DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "%s: register_servable failed blk=%d", MDL_ID, n);
}
}
DEBUG_INFO(DEBUG_CATEGORY_MEDIA, "%s: registered %d downloaded blocks as servable (%s)",
MDL_ID, dl->num_blocks, rel);
if (!db) { DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "%s: register_servable without DB", MDL_ID); return -1; }
char chat_id[32]; snprintf(chat_id, sizeof(chat_id), "%llu", (unsigned long long)dl->group_id);
uint8_t* ids = u_malloc((uint32_t)dl->num_blocks * 16);
if (!ids) { DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "%s: register_servable allocation failed", MDL_ID); return -1; }
for (int n = 0; n < dl->num_blocks; n++) memcpy(ids + (size_t)n * 16, dl->blocks[n].block_id, 16);
struct media_index_result result = { .file_size = dl->file_size, .block_size = dl->block_size,
.num_blocks = dl->num_blocks, .block_ids = ids };
memcpy(result.media_id, dl->media_id, 16); memcpy(result.content_hash, dl->content_hash, 32);
int rc = media_index_register_downloaded_file(db, &result, inst->node_id, chat_id, dl->dest_path, dl->media_base);
u_free(ids); return rc;
}
void media_download_handle_done(struct UTUN_INSTANCE* inst,
@@ -783,8 +772,8 @@ void media_download_handle_done(struct UTUN_INSTANCE* inst,
} }
dl->assembled = 1;
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "%s: file assembled: %s", MDL_ID, dl->dest_path);
md_dl_register_servable(dl);
md_dl_finish(dl, 0);
int registered = md_dl_register_servable(dl);
md_dl_finish(dl, registered);
return;
}
@@ -877,6 +866,15 @@ int media_download_start(struct UTUN_INSTANCE* inst, uint64_t group_id,
struct media_delivery_ctx* md = &inst->md;
if (!md->initialized) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "%s: start before media_delivery init", MDL_ID); return -1; }
char location[MEDIA_PATH_MAX];
if (result->file_size <= 0 || result->block_size <= 0 || result->block_size > UINT32_MAX
|| result->num_blocks <= 0 || (uint64_t)result->num_blocks > UINT32_MAX / 64
|| (result->file_size - 1) / result->block_size + 1 != result->num_blocks
|| !result->block_ids || !result->block_sigs || media_index_location(dest_path, media_base, location)
|| media_index_set_base(inst->topo_sqlite_db, media_base)) {
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "%s: invalid file geometry/path/base before download", MDL_ID); return -1;
}
/* дедуп: та же медиа уже качается */
if (md_dl_find(inst, result->media_id)) {
DEBUG_WARN(DEBUG_CATEGORY_GENERAL, "%s: DUPLICATE download media=%02x%02x... ignored", MDL_ID, result->media_id[0], result->media_id[1]);
@@ -933,15 +931,6 @@ int media_download_start(struct UTUN_INSTANCE* inst, uint64_t group_id,
dl = (struct media_download*)qe->data;
/* сохраняем media_base в ui_state — чтобы после скачивания узел мог отдавать блоки
(md_handle_block_req открывает файл по ui_state.media_base + location) */
{
sqlite3_exec(inst->topo_sqlite_db, "CREATE TABLE IF NOT EXISTS ui_state(key TEXT PRIMARY KEY, value TEXT)", NULL, NULL, NULL);
sqlite3_stmt* us = NULL;
sqlite3_prepare_v2(inst->topo_sqlite_db, "INSERT OR REPLACE INTO ui_state(key,value) VALUES('media_base',?)", -1, &us, NULL);
if (us) { sqlite3_bind_text(us, 1, media_base, -1, SQLITE_STATIC); sqlite3_step(us); sqlite3_finalize(us); }
}
md_dl_collect_supernodes(inst, dl);
dl->last_activity_tb = get_time_tb();
dl->watchdog_timer = uasync_set_timeout(inst->ua, (int)md_dl_stall_tb(inst), dl, md_dl_watchdog_cb, "md_dl_wd");