Restore retained attachment indexes during startup and manual download
This commit is contained in:
1 parent
d9f5da130e
commit
fdb11ed3ce
3 files changed
+28
-5
No files matched your search
@@ -19,6 +19,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#define CC_ID "chat_core"
|
||||
#define CHAT_MEDIA_BACKFILL_CHANNELS 16
|
||||
|
||||
/* ── Base64 encode/decode (URL-safe, used for msg "d" field prefix) ── */
|
||||
|
||||
@@ -100,7 +101,7 @@ struct chat_core_ctx {
|
||||
int media_backfill_ran; /* was chat_msg.c g_media_startup_backfill_ran */
|
||||
struct UTUN_INSTANCE* media_backfill_inst; /* was chat_msg.c g_media_startup_backfill_inst */
|
||||
void* media_channel_backfill_timer; /* ограниченный batch докачки/восстановления индекса через 2с от первой заявки */
|
||||
char media_channel_backfill[16][64]; /* pending ch_id */
|
||||
char media_channel_backfill[CHAT_MEDIA_BACKFILL_CHANNELS][64]; /* pending ch_id */
|
||||
int media_channel_backfill_pending;
|
||||
void* attachment_timer;
|
||||
int attachment_closing;
|
||||
|
||||
+25
-3
@@ -752,7 +752,11 @@ static int msg_read_id(struct chat_core_ctx* cc, const char* channel, int64_t id
|
||||
const void* key = sqlite3_column_blob(st, 0);
|
||||
if (key) { memcpy(message_id, key, 32); result = 0; }
|
||||
}
|
||||
sqlite3_finalize(st);
|
||||
int final_rc = sqlite3_finalize(st);
|
||||
if (final_rc != SQLITE_OK) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "media identity finalize failed ch=%s id=%lld rc=%d", channel, (long long)id, final_rc);
|
||||
result = -1;
|
||||
}
|
||||
if (result) DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "media identity missing ch=%s id=%lld rc=%d: %s",
|
||||
channel, (long long)id, rc, sqlite3_errmsg(cc->db));
|
||||
return result;
|
||||
@@ -1227,7 +1231,7 @@ void chat_media_backfill(struct UTUN_INSTANCE* inst) {
|
||||
char tbl[80]; msg_table_name(ch_id, tbl, sizeof(tbl));
|
||||
|
||||
char sql[256];
|
||||
snprintf(sql, sizeof(sql), "SELECT data FROM \"%s\"", tbl);
|
||||
snprintf(sql, sizeof(sql), "SELECT data,message_id,node_id FROM \"%s\"", tbl);
|
||||
sqlite3_stmt* ms = NULL;
|
||||
if (sqlite3_prepare_v2(cc->db, sql, -1, &ms, NULL) != SQLITE_OK) continue;
|
||||
|
||||
@@ -1260,6 +1264,22 @@ void chat_media_backfill(struct UTUN_INSTANCE* inst) {
|
||||
content_type[i] = '\0';
|
||||
}
|
||||
|
||||
int encrypted_attachment = !strcmp(content_type, ENCRYPTED_ATTACHMENT_TYPE);
|
||||
uint8_t message[32];
|
||||
if (encrypted_attachment) {
|
||||
if (sqlite3_column_bytes(ms, 1) != 32 || !sqlite3_column_blob(ms, 1)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "media startup: missing encrypted message identity ch=%s", ch_id);
|
||||
media_index_result_free(&result); u_free(body); continue;
|
||||
}
|
||||
memcpy(message, sqlite3_column_blob(ms, 1), 32);
|
||||
int observed = chat_attachment_observe(inst, ch_id, message, (uint64_t)sqlite3_column_int64(ms, 2), jdata,
|
||||
(size_t)sqlite3_column_bytes(ms, 0));
|
||||
if (observed) {
|
||||
if (observed == -1) media_queue_channel_backfill(inst, ch_id);
|
||||
media_index_result_free(&result); u_free(body); continue;
|
||||
}
|
||||
}
|
||||
|
||||
char base_filename[256];
|
||||
extract_base_filename(body, base_filename, sizeof(base_filename));
|
||||
char final_name[256];
|
||||
@@ -1277,6 +1297,8 @@ void chat_media_backfill(struct UTUN_INSTANCE* inst) {
|
||||
int registered = media_index_commit(cc->db, &result, cc->my_node_id, NULL, ch_id, path, media_base);
|
||||
if (!registered) total += result.num_blocks;
|
||||
else DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "media backfill registration failed ch=%s file=%s", ch_id, path);
|
||||
if (encrypted_attachment && !registered && chat_attachment_downloaded(inst, ch_id, message))
|
||||
media_queue_channel_backfill(inst, ch_id);
|
||||
|
||||
u_free(body);
|
||||
media_index_result_free(&result);
|
||||
@@ -1882,7 +1904,7 @@ static void media_channel_backfill_timer_cb(void* arg) {
|
||||
struct chat_core_ctx* cc = CC(inst);
|
||||
if (!cc) return;
|
||||
cc->media_channel_backfill_timer = NULL;
|
||||
char channels[16][64]; int count = cc->media_channel_backfill_pending;
|
||||
char channels[CHAT_MEDIA_BACKFILL_CHANNELS][sizeof(cc->media_channel_backfill[0])]; int count = cc->media_channel_backfill_pending;
|
||||
memcpy(channels, cc->media_channel_backfill, (size_t)count * sizeof(channels[0]));
|
||||
cc->media_channel_backfill_pending = 0;
|
||||
for (int i = 0; i < count; i++) chat_media_autodownload_backfill_channel(inst, channels[i]);
|
||||
|
||||
+1
-1
@@ -848,8 +848,8 @@ int chat_service_start(struct UTUN_INSTANCE* instance) {
|
||||
if (chat_attachment_init(instance) < 0) goto fail;
|
||||
if (member_files_init(instance) < 0 || dm_mailbox_init(instance) < 0 || dm_core_init(instance) < 0 ||
|
||||
dm_media_init(instance) < 0 || call_init(instance) < 0 || radio_call_init(instance) < 0) goto fail;
|
||||
chat_media_backfill(instance);
|
||||
chat_media_startup_backfill_init(instance);
|
||||
chat_media_backfill(instance);
|
||||
/* Все headless listeners используют IPv4:port; port=0 выбирает ОС. Ошибка отключает только этот listener. */
|
||||
const struct {
|
||||
const char* bind;
|
||||
|
||||
Reference in new issue
Block a user