feat(raft-log-replication): raft_send_append_entries AppendEntries emit (tasks 4.1, 4.2)
Leader-only emit (raft.tla AppendEntries:204, Req 3.5 — no-op off leader); prev_log_index=next_index[j]-1, prev_log_term via on_get_entry_term (0/unqueried at index 0, Req 3.2-3.3); n_entries=1 when next_index[j]<=log_len else 0 heartbeat (Req 3.4); leader_commit opaque passthrough. Trace fires only on successful send (consistency with raft_log_append) and non-leader RAFT_OK asserted — both from review. 4 spy-based tests. ASAN green.
This commit is contained in:
parent
e5b9b83955
commit
a1aacc0389
3 changed files with 247 additions and 2 deletions
|
|
@ -503,3 +503,41 @@ int raft_log_append(raft_state_t *s, const void *entry, size_t len,
|
|||
|
||||
return RAFT_OK;
|
||||
}
|
||||
|
||||
int raft_send_append_entries(raft_state_t *s, int peer_idx,
|
||||
uint64_t leader_commit)
|
||||
{
|
||||
/* Leader-only (Req 3.5): AppendEntries is enabled only at the leader in
|
||||
* raft.tla. Off the leader this is a no-op — no callback, no state change. */
|
||||
if (s->role != RAFT_LEADER)
|
||||
return RAFT_OK;
|
||||
|
||||
/* prevLogIndex = nextIndex[j] - 1; prevLogTerm = on_get_entry_term(prevIdx)
|
||||
* when prevIdx > 0, else 0 (the "absent" sentinel, matching raft.tla
|
||||
* prevLogTerm == 0 when prevLogIndex == 0). Do NOT query the callback at
|
||||
* index 0 (Req 3.2). */
|
||||
uint64_t prev_log_index = s->next_index[peer_idx] - 1;
|
||||
uint64_t prev_log_term = (prev_log_index > 0)
|
||||
? s->cbs->on_get_entry_term(s->ctx, prev_log_index)
|
||||
: 0;
|
||||
|
||||
/* lastEntry = Min(log_len, next_index[j]); send SubSeq(log, next_index[j],
|
||||
* lastEntry) — at most one entry. When next_index[j] > log_len there is
|
||||
* nothing to send → a 0-entry heartbeat (Req 3.3). */
|
||||
int n_entries = (s->next_index[peer_idx] <= s->log_len) ? 1 : 0;
|
||||
|
||||
/* leader_commit is passed through opaquely; this spec never interprets or
|
||||
* advances commit (Req 3.4 — commit is owned by raft-commit-safety). */
|
||||
int rc = s->cbs->on_send_append_entries(s->ctx, peer_idx, prev_log_index,
|
||||
prev_log_term, leader_commit,
|
||||
n_entries);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
/* Trace only on a successful send (mirrors raft_log_append, which traces
|
||||
* after a confirmed persist) — a failed emit must not look successful. */
|
||||
if (s->cbs->on_trace)
|
||||
s->cbs->on_trace(s->ctx, "ae_send", NULL);
|
||||
|
||||
return RAFT_OK;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue