feat(ha-commit-durability): add --wal-sync-ms flush-cadence override (task 1.1)
This commit is contained in:
parent
80bb1d766e
commit
1ca2d640cb
7 changed files with 206 additions and 0 deletions
|
|
@ -1270,6 +1270,11 @@ int cluster_init_phase2(cluster_t* c)
|
|||
if (c->myconf->sync_timeout_ms > 0)
|
||||
pcfg.sync_timeout_ms = c->myconf->sync_timeout_ms;
|
||||
|
||||
/* --wal-sync-ms flush-cadence override (0 = keep the persist
|
||||
* default). Applied before persist_init so persistence starts at
|
||||
* the requested cadence (ha-commit-durability Req 3.1). */
|
||||
persist_config_set_wal_sync_ms(&pcfg, c->myconf->wal_sync_ms);
|
||||
|
||||
persist_set_workdir(&c->persist, workdir, name);
|
||||
rc = persist_init(&c->persist, &pcfg, c);
|
||||
if (rc != 0) {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ const char* argp_program_bug_address = BUG_EMAIL;
|
|||
#define OPT_VCPUS 259
|
||||
#define OPT_CERTDIR 260
|
||||
#define OPT_SYNC_TIMEOUT 261
|
||||
#define OPT_WAL_SYNC 262
|
||||
|
||||
struct arguments {
|
||||
char* myname;
|
||||
|
|
@ -42,6 +43,7 @@ struct arguments {
|
|||
int vcpus;
|
||||
char* certdir;
|
||||
uint32_t sync_timeout_ms;
|
||||
uint32_t wal_sync_ms;
|
||||
};
|
||||
|
||||
static struct argp_option options[] = {
|
||||
|
|
@ -62,6 +64,8 @@ static struct argp_option options[] = {
|
|||
"Directory containing xce.crt and xce.key (default: <workdir>/certs)" },
|
||||
{ "sync-timeout-ms", OPT_SYNC_TIMEOUT, "MS", 0,
|
||||
"Synchronous majority-replication commit barrier timeout in ms (0 = default)" },
|
||||
{ "wal-sync-ms", OPT_WAL_SYNC, "MS", 0,
|
||||
"WAL flush (fsync) cadence in ms (0 = default)" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
|
@ -111,6 +115,13 @@ static error_t parse_opt(int key, char* arg, struct argp_state* state)
|
|||
arguments->sync_timeout_ms = (uint32_t)v;
|
||||
break;
|
||||
}
|
||||
case OPT_WAL_SYNC: {
|
||||
int v = atoi(arg);
|
||||
if (v < 0)
|
||||
argp_error(state, "--wal-sync-ms must be >= 0 (got: %s)", arg);
|
||||
arguments->wal_sync_ms = (uint32_t)v;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
|
|
@ -163,6 +174,7 @@ int main(int argc, char* argv[])
|
|||
arguments.conf_stale_timeout = 86400;
|
||||
arguments.vcpus = 0; /* 0 = not set; use cluster config default */
|
||||
arguments.sync_timeout_ms = 0; /* 0 = not set; use persist config default */
|
||||
arguments.wal_sync_ms = 0; /* 0 = not set; use persist config default */
|
||||
|
||||
argp_parse(&argp, argc, argv, 0, 0, &arguments);
|
||||
|
||||
|
|
@ -212,6 +224,7 @@ int main(int argc, char* argv[])
|
|||
myconf.conf_stale_timeout = (time_t)arguments.conf_stale_timeout;
|
||||
myconf.vcpus = arguments.vcpus;
|
||||
myconf.sync_timeout_ms = arguments.sync_timeout_ms;
|
||||
myconf.wal_sync_ms = arguments.wal_sync_ms;
|
||||
memset(&myconf.peers_cfg, 0, sizeof(myconf.peers_cfg));
|
||||
|
||||
if (arguments.peers_str) {
|
||||
|
|
|
|||
|
|
@ -163,6 +163,11 @@ int myapp_run(myconf_t *myconf)
|
|||
: "controller";
|
||||
persist_config_t pcfg = persist_config_defaults();
|
||||
|
||||
/* --wal-sync-ms flush-cadence override (0 = keep the persist
|
||||
* default). Applied before persist_init so persistence starts at
|
||||
* the requested cadence (ha-commit-durability Req 3.1). */
|
||||
persist_config_set_wal_sync_ms(&pcfg, myconf->wal_sync_ms);
|
||||
|
||||
persist_set_workdir(&c.persist, workdir, name);
|
||||
rc = persist_init(&c.persist, &pcfg, &c);
|
||||
if (rc != 0) {
|
||||
|
|
|
|||
|
|
@ -68,6 +68,44 @@ static void test_persist_config_defaults_sync_timeout_ms(void)
|
|||
TEST_ASSERT_EQUAL_UINT32(DEFAULT_SYNC_TIMEOUT_MS, cfg.sync_timeout_ms);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* --wal-sync-ms flush-cadence override (ha-commit-durability task 1.1) */
|
||||
/* */
|
||||
/* persist_config_set_wal_sync_ms() is the single override point shared */
|
||||
/* by both persist_config_defaults() callers (cluster.c phase2 and */
|
||||
/* myapp.c step 6). It mirrors the --sync-timeout-ms convention: a */
|
||||
/* value of 0 means "flag not passed" and preserves the default; a */
|
||||
/* positive value sets the flush cadence to exactly that. */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static void test_wal_sync_ms_override_applies_positive_value(void)
|
||||
{
|
||||
persist_config_t cfg = persist_config_defaults();
|
||||
persist_config_set_wal_sync_ms(&cfg, 250);
|
||||
TEST_ASSERT_EQUAL_UINT32(250, cfg.wal_sync_ms);
|
||||
}
|
||||
|
||||
static void test_wal_sync_ms_override_zero_preserves_default(void)
|
||||
{
|
||||
persist_config_t cfg = persist_config_defaults();
|
||||
/* 0 = flag omitted: cadence must stay byte-for-byte the default
|
||||
* (Req 3.3 — the seam changes timing controllability only). */
|
||||
persist_config_set_wal_sync_ms(&cfg, 0);
|
||||
TEST_ASSERT_EQUAL_UINT32(DEFAULT_WAL_SYNC_MS, cfg.wal_sync_ms);
|
||||
}
|
||||
|
||||
static void test_wal_sync_ms_override_leaves_other_fields_intact(void)
|
||||
{
|
||||
persist_config_t cfg = persist_config_defaults();
|
||||
persist_config_set_wal_sync_ms(&cfg, 7);
|
||||
/* Only the cadence changes; every other persistence default is
|
||||
* preserved (Req 3.3 — no behavioral change beyond timing). */
|
||||
TEST_ASSERT_EQUAL_UINT32(7, cfg.wal_sync_ms);
|
||||
TEST_ASSERT_EQUAL_UINT32(DEFAULT_SNAP_INTERVAL_S, cfg.snap_interval_s);
|
||||
TEST_ASSERT_EQUAL_UINT32(DEFAULT_SYNC_TIMEOUT_MS, cfg.sync_timeout_ms);
|
||||
TEST_ASSERT_EQUAL_UINT32(DEFAULT_MAX_WAL_RECORDS, cfg.max_wal_records);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* persist_set_workdir derives correct paths */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
|
@ -103,6 +141,9 @@ void test_cluster_persist(void)
|
|||
RUN_TEST(test_persist_config_defaults_snap_keep_n);
|
||||
RUN_TEST(test_persist_config_defaults_finished_retain_s);
|
||||
RUN_TEST(test_persist_config_defaults_sync_timeout_ms);
|
||||
RUN_TEST(test_wal_sync_ms_override_applies_positive_value);
|
||||
RUN_TEST(test_wal_sync_ms_override_zero_preserves_default);
|
||||
RUN_TEST(test_wal_sync_ms_override_leaves_other_fields_intact);
|
||||
RUN_TEST(test_persist_set_workdir_derives_wal_path);
|
||||
RUN_TEST(test_persist_set_workdir_derives_snap_path);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ typedef struct {
|
|||
int conf_stale; /* 1 when saved config older than conf_stale_timeout */
|
||||
int vcpus; /* Req 4.3: --vcpus CLI value; 0 = use config default */
|
||||
uint32_t sync_timeout_ms; /* --sync-timeout-ms; 0 = use persist default */
|
||||
uint32_t wal_sync_ms; /* --wal-sync-ms; 0 = use persist default */
|
||||
} myconf_t;
|
||||
|
||||
extern cluster_config_t* get_default_conf(void*);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,24 @@ static inline persist_config_t persist_config_defaults(void)
|
|||
return c;
|
||||
}
|
||||
|
||||
/*
|
||||
* persist_config_set_wal_sync_ms — apply the --wal-sync-ms flush-cadence
|
||||
* override (ha-commit-durability Req 3.1).
|
||||
*
|
||||
* Single override point shared by both persist_config_defaults() callers
|
||||
* (cluster.c phase2 and myapp.c step 6), mirroring the --sync-timeout-ms
|
||||
* convention: override_ms == 0 means "flag not passed" and leaves the
|
||||
* default flush cadence untouched (Req 3.3 — the seam changes timing
|
||||
* controllability only, not the durability contract). A positive value
|
||||
* sets the cadence to exactly that, applied before persistence starts.
|
||||
*/
|
||||
static inline void persist_config_set_wal_sync_ms(persist_config_t *c,
|
||||
uint32_t override_ms)
|
||||
{
|
||||
if (override_ms > 0)
|
||||
c->wal_sync_ms = override_ms;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* Key→index mapping for checkpoint serialization (Part 3.8)
|
||||
* ============================================================ */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue