db_sync: async batch chain_hash recalc (batch 50, timeout 0→100tb), flush before protocol chain_hash reads, remove db_cascade_from/range + do_cascade param

This commit is contained in:
evgeny committed 2026-07-30 15:53:23 +03:00
1 parent df13b16fad
commit c093630d4d
2 files changed
+167 -141

No files matched your search

+35 -23
View File
@@ -45,6 +45,7 @@ static void* timeout_id = NULL;
static char temp_dir[] = "/tmp/utun_dbsync_XXXXXX";
static char config_a[256], config_b[256], config_c[256];
static int port_a_srv, port_b_srv, port_c_srv;
static uint32_t ca_target, cb_target, cc_target;
static int write_file(const char* path, const char* fmt, ...) {
va_list ap; FILE* f = fopen(path, "w");
@@ -123,7 +124,13 @@ static int wait_for(const char* desc, int (*cond)(void), int timeout_tb) {
while (!cond() && (get_time_tb() - start) < (uint64_t)timeout_tb && test_phase == 0)
uasync_poll(ua, POLL_INTERVAL_MS);
if (cond()) return 1;
if (test_phase == 0) { fprintf(stderr, "TIMEOUT: %s\n", desc); test_phase = 2; }
if (test_phase == 0) {
fprintf(stderr, "TIMEOUT: %s — ca=%u/%u cb=%u/%u cc=%u/%u\n", desc,
si_a ? db_sync_count(si_a) : 0, ca_target,
si_b ? db_sync_count(si_b) : 0, cb_target,
si_c ? db_sync_count(si_c) : 0, cc_target);
test_phase = 2;
}
return 0;
}
@@ -136,7 +143,6 @@ static int cond_links_init(void) {
e = e->next; }
return links >= (inst_c ? 2 : 1);
}
static uint32_t ca_target, cb_target, cc_target;
static int _cond_ca(void) { return si_a && db_sync_count(si_a) == ca_target; }
static int _cond_cb(void) { return si_b && db_sync_count(si_b) == cb_target; }
static int _cond_cc(void) { return si_c && db_sync_count(si_c) == cc_target; }
@@ -367,29 +373,34 @@ int main(void) {
total += 5;
}
// -- Round 3: simulate disconnect (reset sync state), add random records, reinitiate, sync --
printf(" R3: disconnect/reset sync state, insert random, reinitiate\n");
db_sync_peer_set_state(si_a, inst_b->node_id, 0); db_sync_peer_set_state(si_a, inst_c->node_id, 0);
db_sync_peer_set_state(si_b, inst_a->node_id, 0);
db_sync_peer_set_state(si_c, inst_a->node_id, 0);
int r3_a = rand() % 2, r3_b = rand() % 2, r3_c = rand() % 2;
total += r3_a + r3_b + r3_c;
printf(" R3: A=%d B=%d C=%d (total=%d)\n", r3_a, r3_b, r3_c, total);
if ((r3_a > 0 && insert_many(si_a, inst_a, 400, r3_a) != 0)
|| (r3_b > 0 && insert_many(si_b, inst_b, 500, r3_b) != 0)
|| (r3_c > 0 && insert_many(si_c, inst_c, 600, r3_c) != 0)) { test_phase = 2; goto done; }
db_sync_reinitiate(si_b, inst_a->node_id);
db_sync_reinitiate(si_c, inst_a->node_id);
ca_target = cb_target = cc_target = (uint32_t)total;
if (!wait_for("R3 converge", _cond_all, PHASE_TIMEOUT_TB)) { test_phase = 2; goto done; }
// -- Round 3: multiple disconnect/reset/sync cycles (stress test the race condition) --
{
uint64_t ha, hb, hc;
if (db_sync_last_chain_hash8(si_a, &ha) || db_sync_last_chain_hash8(si_b, &hb)
|| db_sync_last_chain_hash8(si_c, &hc) || ha != hb || hb != hc) { test_phase = 2; goto done; }
int rnd_rounds = 5; // run 5 sub-rounds to catch rare race conditions
for (int r = 0; r < rnd_rounds && test_phase == 0; r++) {
printf(" R3.%d: disconnect/reset, insert random, reinitiate\n", r);
db_sync_peer_set_state(si_a, inst_b->node_id, 0); db_sync_peer_set_state(si_a, inst_c->node_id, 0);
db_sync_peer_set_state(si_b, inst_a->node_id, 0); db_sync_peer_set_state(si_b, inst_c->node_id, 0);
db_sync_peer_set_state(si_c, inst_a->node_id, 0); db_sync_peer_set_state(si_c, inst_b->node_id, 0);
int ra = rand() % 3, rb = rand() % 3, rc = rand() % 3;
total += ra + rb + rc;
printf(" R3.%d: A=%d B=%d C=%d (total=%d)\n", r, ra, rb, rc, total);
if ((ra > 0 && insert_many(si_a, inst_a, 400 + r*100, ra) != 0)
|| (rb > 0 && insert_many(si_b, inst_b, 500 + r*100, rb) != 0)
|| (rc > 0 && insert_many(si_c, inst_c, 600 + r*100, rc) != 0)) { test_phase = 2; goto done; }
db_sync_reinitiate(si_b, inst_a->node_id);
db_sync_reinitiate(si_c, inst_a->node_id);
ca_target = cb_target = cc_target = (uint32_t)total;
if (!wait_for("R3 converge", _cond_all, PHASE_TIMEOUT_TB)) { test_phase = 2; goto done; }
{
uint64_t ha, hb, hc;
if (db_sync_last_chain_hash8(si_a, &ha) || db_sync_last_chain_hash8(si_b, &hb)
|| db_sync_last_chain_hash8(si_c, &hc) || ha != hb || hb != hc) { test_phase = 2; goto done; }
}
}
}
printf(" R3 PASS (%u records)\n", ca_target);
if (test_phase == 0) printf(" R3 PASS (%u records)\n", ca_target);
done:
remove_si(&si_a); remove_si(&si_b); remove_si(&si_c);
@@ -400,6 +411,7 @@ done:
if (ua) { uasync_destroy(ua, 0); ua = NULL; }
cleanup_temp_configs();
if (test_phase == 0) test_phase = 1;
debug_disable_file_output();
printf("=== %s ===\n", test_phase == 1 ? "PASS" : "FAIL");
return test_phase == 1 ? 0 : 1;
}