forked from lei.chen/myxce
feat(ha-commit-durability): cap commit self-contribution at durable_lsn + durable-advance commit wake (task 2.2)
This commit is contained in:
parent
cc83caf5a0
commit
c41edc515e
10 changed files with 395 additions and 13 deletions
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <unity/unity.h>
|
||||
|
||||
#include "commit.h"
|
||||
#include "config.h"
|
||||
#include "persist.h"
|
||||
|
||||
|
|
@ -433,6 +434,69 @@ static void test_durable_lsn_holds_on_fsync_failure(void)
|
|||
printf("test_durable_lsn_holds_on_fsync_failure: PASS\n");
|
||||
}
|
||||
|
||||
/* ================================================================== *
|
||||
* task 2.2 — durable-advance wake drives commit (integration) *
|
||||
* *
|
||||
* End-to-end over a REAL persist_t + commit_engine_t (single-member, *
|
||||
* NULL cluster): the group-commit flusher advances durable_lsn and *
|
||||
* fires the registered durable-advance callback, which the commit *
|
||||
* engine uses to advance committed_lsn and wake WAIT callers. Proves *
|
||||
* the persist↔commit wiring works against the real flusher thread — *
|
||||
* not just the directly-driven callback (covered in *
|
||||
* test_commit_engine.c). n_peers=1 means self alone is the majority, *
|
||||
* so committed_lsn tracks durable_lsn with no standby ACKs needed. *
|
||||
* ------------------------------------------------------------------ */
|
||||
static void test_durable_advance_drives_commit_single_member(void)
|
||||
{
|
||||
char tmp[256];
|
||||
strcpy(tmp, "/tmp/xce_durcommit_XXXXXX");
|
||||
TEST_ASSERT_NOT_NULL(mkdtemp(tmp));
|
||||
|
||||
persist_t* p = make_durability_persist(tmp);
|
||||
TEST_ASSERT_NOT_NULL(p);
|
||||
|
||||
/* Single-member commit engine over the real persist. n_vcpus large enough
|
||||
* to admit a wait. commit_engine_init registers the durable-advance cb. */
|
||||
commit_engine_t ce;
|
||||
TEST_ASSERT_EQUAL_INT(0, commit_engine_init(&ce, p, 1, 8));
|
||||
|
||||
/* committed starts at 0; nothing appended/durable. */
|
||||
TEST_ASSERT_EQUAL_UINT64(0, atomic_load(&p->committed_lsn));
|
||||
|
||||
/* Append three entries (LSN 1,2,3). They are in page cache only — the slow
|
||||
* 5s cadence means the append-SIGNAL (not the timer) must drive the flush;
|
||||
* the real flusher fdatasyncs, advances durable_lsn, and fires the cb,
|
||||
* which advances committed_lsn for this single-member quorum. */
|
||||
TEST_ASSERT_EQUAL_INT(0, persist_wal_async(p, WAL_JOB_UPDATE, "a", 1));
|
||||
TEST_ASSERT_EQUAL_INT(0, persist_wal_async(p, WAL_JOB_UPDATE, "b", 1));
|
||||
TEST_ASSERT_EQUAL_INT(0, persist_wal_async(p, WAL_JOB_UPDATE, "c", 1));
|
||||
|
||||
uint64_t tip = p->current_lsn - 1; /* 3 */
|
||||
TEST_ASSERT_EQUAL_UINT64(3, tip);
|
||||
|
||||
/* Wait for the flusher to make the tip durable AND for the wake-driven
|
||||
* commit to catch up. committed_lsn must reach the tip — driven by the
|
||||
* durable-advance callback, not by any ACK (there are no standbys). */
|
||||
uint64_t committed = 0;
|
||||
for (int i = 0; i < 5000; i++) {
|
||||
committed = atomic_load(&p->committed_lsn);
|
||||
if (committed >= tip)
|
||||
break;
|
||||
usleep(1000);
|
||||
}
|
||||
TEST_ASSERT_EQUAL_UINT64_MESSAGE(
|
||||
tip, committed,
|
||||
"durable-advance callback must drive committed_lsn to the durable tip");
|
||||
/* committed never exceeds durable (the invariant the wake preserves). */
|
||||
TEST_ASSERT_TRUE(atomic_load(&p->committed_lsn) <= persist_durable_lsn(p));
|
||||
|
||||
/* Tear the engine down BEFORE the persist (unhooks the callback so the
|
||||
* flusher cannot fire against a destroyed engine). */
|
||||
commit_engine_fini(&ce);
|
||||
teardown_durability_persist(p);
|
||||
printf("test_durable_advance_drives_commit_single_member: PASS\n");
|
||||
}
|
||||
|
||||
#endif /* XCE_TESTING */
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
|
@ -449,6 +513,7 @@ void test_commit_durability(void)
|
|||
RUN_TEST(test_durable_lsn_never_exceeds_synced_tip);
|
||||
RUN_TEST(test_durable_lsn_invariants_under_load);
|
||||
RUN_TEST(test_durable_lsn_holds_on_fsync_failure);
|
||||
RUN_TEST(test_durable_advance_drives_commit_single_member);
|
||||
#else
|
||||
printf("test_commit_durability: skipped (no XCE_TESTING)\n");
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue