feat(raft-apply-decoupling): add commit engine continuation registration (task 1.1)
commit_submit_async() lets a WAIT-mode caller register a continuation against an appended LSN instead of blocking on pthread_cond_timedwait, reusing the existing admission-cap discipline (wait_admit_locked/ wait_release_locked) so the bounded-capacity guarantee carries over unchanged. Purely additive: no existing call site (repl_wait_majority_ack) is touched yet -- that switch lands in task 3.2 once commit_resolve() (task 1.2) exists to drive it.
This commit is contained in:
parent
3ecb724984
commit
10d157f8c5
6 changed files with 457 additions and 1 deletions
|
|
@ -23,6 +23,32 @@
|
|||
|
||||
typedef enum { COMMIT_MODE_WAIT, COMMIT_MODE_RETAIN } commit_mode_t;
|
||||
|
||||
/* raft-apply-decoupling task 1.1: event-driven resolve outcome, delivered to
|
||||
* a registered continuation in place of a COMMIT_MODE_WAIT caller's blocking
|
||||
* return value. COMMITTED mirrors commit_submit's rc==0; FAILED mirrors any
|
||||
* of commit_submit's negative outcomes (timeout, demotion, truncation), with
|
||||
* the specific cause carried in the continuation's `rc` argument. */
|
||||
typedef enum { COMMIT_OUTCOME_COMMITTED, COMMIT_OUTCOME_FAILED } commit_outcome_t;
|
||||
|
||||
/* Invoked exactly once per registered lsn when its outcome becomes known.
|
||||
* Delivered via commit_resolve (wired by a follow-up task onto
|
||||
* commit_advance_locked's majority path and the existing timeout/demotion/
|
||||
* truncation failure handling), dispatched off the calling thread via
|
||||
* vtask_enq_classified -- never inline on the replication-ACK or iomgr
|
||||
* path. */
|
||||
typedef void (*commit_continuation_fn)(void* ctx, uint64_t lsn,
|
||||
commit_outcome_t outcome, int rc);
|
||||
|
||||
/* raft-apply-decoupling task 1.1: one registered COMMIT_MODE_WAIT-equivalent
|
||||
* continuation. lsn == 0 marks a free slot -- LSN 0 is the reserved
|
||||
* empty/none sentinel (see persist.h reserve-lsn-0), so it is never a real
|
||||
* registration and is safe as the "unused" marker. */
|
||||
typedef struct commit_continuation {
|
||||
uint64_t lsn;
|
||||
commit_continuation_fn fn;
|
||||
void* ctx;
|
||||
} commit_continuation_t;
|
||||
|
||||
/*
|
||||
* Commit engine state — in-memory only (commit state volatile, Raft-conformant).
|
||||
* Per-standby view delegated to standby_conn_t.acked_lsn / in_catch_up via
|
||||
|
|
@ -52,6 +78,18 @@ typedef struct commit_engine {
|
|||
* non-decreasing, set under ce->lock via commit_set_raft_commit_index. */
|
||||
uint64_t raft_commit_index;
|
||||
uint64_t scratch[MAX_STANDBYS]; /* sorted matchIndex scratch array */
|
||||
/* raft-apply-decoupling task 1.1: per-LSN continuation registry for
|
||||
* commit_submit_async (event-driven resolve, replacing the
|
||||
* COMMIT_MODE_WAIT blocking-park model). Sized to n_vcpus at init: the
|
||||
* SAME admission-cap discipline (wait_admit_locked/wait_cap, the shared
|
||||
* inflight_waits budget) bounds concurrent registrations to
|
||||
* wait_cap(ce) <= n_vcpus, so n_vcpus slots always suffice regardless of
|
||||
* the blocking/async call mix. Resolution (commit_resolve, invoked from
|
||||
* commit_advance_locked and the timeout/demotion/truncation failure
|
||||
* paths) is wired by a follow-up task; until then a registered slot is
|
||||
* inert -- nothing reads it back. */
|
||||
commit_continuation_t* continuations;
|
||||
int n_continuations; /* capacity, == n_vcpus */
|
||||
} commit_engine_t;
|
||||
|
||||
/* Lifecycle. init validates n_peers >= 0, n_vcpus >= 1, non-NULL persist_t;
|
||||
|
|
@ -76,6 +114,19 @@ void commit_set_pool(commit_engine_t* ce, vtaskmgr_t* pool);
|
|||
int commit_submit(commit_engine_t* ce, uint64_t lsn, commit_mode_t mode,
|
||||
uint32_t timeout_ms);
|
||||
|
||||
/* raft-apply-decoupling task 1.1: register a continuation for lsn instead of
|
||||
* parking the calling thread -- the event-driven equivalent of
|
||||
* commit_submit(..., COMMIT_MODE_WAIT, ...). Returns 0 on successful
|
||||
* registration; -EINVAL on bad args (ce/p NULL, lsn == 0, fn == NULL);
|
||||
* -XCE_ERR_NOT_READY when the admission cap is exhausted (the same shared
|
||||
* discipline commit_submit's WAIT mode uses -- see wait_admit_locked).
|
||||
* Never blocks: the calling thread returns immediately, before lsn's
|
||||
* outcome is known. Registering here does not yet cause `fn` to be
|
||||
* invoked -- delivery is commit_resolve's job, added by a follow-up task
|
||||
* that wires it onto the majority-commit and failure paths. */
|
||||
int commit_submit_async(commit_engine_t* ce, uint64_t lsn,
|
||||
commit_continuation_fn fn, void* ctx);
|
||||
|
||||
/* iomgr path: record standby ACK, evaluate majority, advance committed_lsn
|
||||
* contiguously, wake satisfied waiters. Never blocks. */
|
||||
void commit_on_ack(commit_engine_t* ce, int standby_idx, uint64_t acked_lsn);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue