feat(raft-log-replication): raft_log_append leader client-entry append (tasks 3.1, 3.2)
Leader-only (-EPERM for follower/candidate, no mutation/callback); index= log_len+1, term=currentTerm (raft.tla ClientRequest:246, Req 2.1-2.4); persist-before-act: on_persist_entry called once BEFORE log_len advances, non-zero return propagated with no phantom entry (Req 2.5); no commit-index advance, no transport I/O. Spy-based tests for all four branches. ASAN green.
This commit is contained in:
parent
fc87a662cd
commit
e5b9b83955
3 changed files with 212 additions and 2 deletions
|
|
@ -470,3 +470,36 @@ int raft_check_and_start_election(raft_state_t *s)
|
|||
(void)rc;
|
||||
return RAFT_ELECTION_STARTED;
|
||||
}
|
||||
|
||||
int raft_log_append(raft_state_t *s, const void *entry, size_t len,
|
||||
uint64_t *out_index)
|
||||
{
|
||||
/* Role gate (Req 2.2): only a leader may grow the log. Reject without any
|
||||
* log mutation or callback (raft.tla ClientRequest is enabled only at the
|
||||
* leader). */
|
||||
if (s->role != RAFT_LEADER)
|
||||
return -EPERM;
|
||||
|
||||
/* Assign the next 1-based index (== WAL LSN) and stamp the leader's current
|
||||
* term, mirroring raft.tla ClientRequest's [term ↦ currentTerm, value ↦ v]
|
||||
* (Req 2.1, 2.3, 2.4). */
|
||||
uint64_t index = s->log_len + 1;
|
||||
uint64_t term = s->term;
|
||||
|
||||
/* Persist-before-act (Req 2.3, 2.5): durably write the entry BEFORE
|
||||
* advancing log_len. On failure, propagate the error verbatim and leave the
|
||||
* log untouched (no phantom entry). */
|
||||
int rc = s->cbs->on_persist_entry(s->ctx, index, term, entry, len);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
/* Commit the append only after a successful persist. */
|
||||
s->log_len = index;
|
||||
if (out_index)
|
||||
*out_index = index;
|
||||
|
||||
if (s->cbs->on_trace)
|
||||
s->cbs->on_trace(s->ctx, "log_append", NULL);
|
||||
|
||||
return RAFT_OK;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue