chat: троттлинг по фазе спячки (member_sync send-only, db_sync sound-aware) + настройка звука

This commit is contained in:
evgeny committed 2026-09-22 01:20:32 +03:00
1 parent 9f89fd0f7a
commit b39b85db13
7 files changed
+106 -8

No files matched your search

+28
View File
@@ -51,6 +51,7 @@ struct SI_PEER {
uint8_t sync_state;
uint64_t sync_start_tb;
uint32_t retry_count;
uint8_t sound_on; /* 1 = пиру важен этот чат (play sound on message), не троттлим */
};
struct DB_SYNC_INSTANCE {
@@ -311,6 +312,7 @@ static struct SI_PEER* si_peer_add(struct DB_SYNC_INSTANCE* si, uint64_t node_id
p = &si->peers[si->peer_count++];
memset(p, 0, sizeof(*p));
p->node_id = node_id;
p->sound_on = 1;
return p;
}
@@ -1475,6 +1477,22 @@ void db_sync_peer_set_state(struct DB_SYNC_INSTANCE* si, uint64_t node_id, uint8
if (p) p->sync_state = state;
}
// Задать per-(chat,peer) флаг «play sound on message» (троттлинг: sound_off + спящий пир → пропуск).
void db_sync_set_peer_sound(struct UTUN_INSTANCE* inst, uint64_t group_id, uint64_t peer_node_id, int sound_on)
{
if (!inst || !inst->db_sync) return;
struct DB_SYNC* db = inst->db_sync;
struct DB_SYNC_INSTANCE* si = db_instance_find(db, group_id);
if (!si) return; /* чат ещё не создан у нас — настройка не критична */
struct SI_PEER* p = si_peer_add(si, peer_node_id);
if (p && p->sound_on != (uint8_t)(sound_on ? 1 : 0)) {
p->sound_on = sound_on ? 1 : 0;
DEBUG_INFO(DEBUG_CATEGORY_CHAT_SYNC, "sync [%s] peer=%016llx sound_on=%d (throttle=%s)",
SI_SHRT(si), (unsigned long long)peer_node_id, p->sound_on,
p->sound_on ? "off" : "on");
}
}
// Гейт авто-синхронизации: пока gated — инстанс не запускает sync автоматически
// (ждёт member_sync/pubkeys). При снятии гейта запускает sync к пирам в sync_state==0.
void db_sync_instance_set_gated(struct DB_SYNC_INSTANCE* si, int gated)
@@ -1552,6 +1570,15 @@ static void db_sync_resume_peer_check(struct DB_SYNC* db)
// Периодическая проверка: запускает синхронизацию для пиров в состоянии sync_state==0,
// детектирует таймауты синхронизации (DB_SYNC_SYNC_TIMEOUT секунд), логирует зависшие.
// Work-driven: перевзводится только пока есть пиры с sync_state != 2.
/* Троттлинг: пир в SLEEP-фазе И чат для него «тихий» (sound_on=0) — пропускаем. */
static int db_sync_peer_throttled(struct DB_SYNC* db, struct SI_PEER* p) {
if (!db || !p) return 0;
if (p->sound_on) return 0; /* чат пиру важен (play sound) — не троттлим */
struct ETCP_CONN* conn = instance_find_conn(db->inst, p->node_id);
return conn && conn->peer_sleep_phase;
}
static void db_sync_peer_check_cb(void* arg)
{
struct DB_SYNC* db = (struct DB_SYNC*)arg;
@@ -1591,6 +1618,7 @@ static void db_sync_peer_check_cb(void* arg)
uint32_t min_pos = UINT32_MAX;
for (int j = 0; j < si->peer_count; j++) {
if (si->peers[j].sync_state == 0 && si->peers[j].synced_pos < min_pos) {
if (db_sync_peer_throttled(db, &si->peers[j])) continue; /* спящий пир в «тихом» чате — пропускаем */
min_pos = si->peers[j].synced_pos;
best = &si->peers[j];
}