feat(raft-adapter-conformance): wire term-adoption into primary-side config-push reply handler
myreq_handler's ReplConfigPushReply branch now routes cack->term through raft_on_higher_term_observed (same entry point the heartbeat-reply and WAL-NACK vectors use), regardless of accept/reject, without altering the existing accept/reject branching. Adds myreq_handler_for_test (XCE_TESTING-only) to drive the real dispatcher in tests, following the peer_ctrl_msg_handler_for_test precedent. Requires cluster.c in controller_unit_test_src plus the established link-satisfying fake stubs for its unrelated switch-case dependencies (same pattern already used by test_worker_join.c and test_commit_barrier_reply.c).
This commit is contained in:
parent
ecf2dac6b2
commit
1e7a7312bf
4 changed files with 229 additions and 1 deletions
|
|
@ -749,6 +749,26 @@ static int myreq_handler(vtask_t* task)
|
|||
&& workreply->data.replconfigpushreplymsg) {
|
||||
repl_config_push_reply_t *cack =
|
||||
workreply->data.replconfigpushreplymsg;
|
||||
|
||||
/* raft-adapter-conformance Req 7.4/7.5: a config-push reply now
|
||||
* carries the replying member's current term (task 1 schema
|
||||
* addition + task 2.1 send side) -- route it through the same
|
||||
* term-discovery entry point the heartbeat-reply and WAL-NACK
|
||||
* vectors already use (bug-1421; ha.c raft_lock-guarded
|
||||
* raft_on_higher_term_observed calls) so a stale-term primary
|
||||
* adopts the higher term and steps down instead of retrying
|
||||
* forever against a standby that has already moved on. Applies
|
||||
* regardless of accept/reject below -- a reject can still carry
|
||||
* a useful higher term. raft_on_higher_term_observed is itself
|
||||
* strictly-greater-than-only (ha-async-io.md Heartbeat Model),
|
||||
* so no separate `>` comparison is needed here; raft_lock
|
||||
* discipline mirrors the vote-request/pre-vote-request branches
|
||||
* above (bug-1435 -- serialize against concurrent raft_state_t
|
||||
* access). */
|
||||
pthread_mutex_lock(&c->ha.raft_lock);
|
||||
(void)raft_on_higher_term_observed(&c->ha.raft, cack->term);
|
||||
pthread_mutex_unlock(&c->ha.raft_lock);
|
||||
|
||||
if (cack->accepted) {
|
||||
repl_on_config_ack(&c->persist.repl, ep, cack->version_tag);
|
||||
TRACE("myreq_handler: config ACK from inbound standby"
|
||||
|
|
@ -779,6 +799,39 @@ static int myreq_handler(vtask_t* task)
|
|||
return rc;
|
||||
}
|
||||
|
||||
#ifdef XCE_TESTING
|
||||
/*
|
||||
* myreq_handler_for_test: expose myreq_handler for tests (peer_ctrl_msg_
|
||||
* handler_for_test precedent, ha.c). Builds the vtask_t/vtask_data_t wrapper
|
||||
* vtask_entry constructs internally in production so a test can decode+
|
||||
* dispatch a real packet through the actual switch -- including the
|
||||
* ReplConfigPushReply branch's term-adoption check (raft-adapter-
|
||||
* conformance Req 7.4/7.5). Packet ownership follows myreq_handler's own
|
||||
* contract: myreq_handler unconditionally calls xce_decode(pkt, ...) as its
|
||||
* first step, and xce_decode() itself consumes pkt -- it calls
|
||||
* free_packet(pkt) (frees pkt->data) and FREEUP(pkt) (frees the io_packet_t
|
||||
* struct) before returning (request.c). Ownership of `pkt` is therefore
|
||||
* TRANSFERRED into this call: the caller must NOT touch or free `pkt` after
|
||||
* calling myreq_handler_for_test -- doing so is a use-after-free/double-free.
|
||||
* (xce_free_request separately releases the decoded xce_request_t, an
|
||||
* unrelated stack-local object in myreq_handler.)
|
||||
*/
|
||||
int myreq_handler_for_test(endpoint_t* ep, io_packet_t* pkt)
|
||||
{
|
||||
vtask_data_t data;
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.vtype = VTASK_IO;
|
||||
data.u.iodata.ep = ep;
|
||||
data.u.iodata.pkt = pkt;
|
||||
|
||||
vtask_t task;
|
||||
memset(&task, 0, sizeof(task));
|
||||
task.data = &data;
|
||||
|
||||
return myreq_handler(&task);
|
||||
}
|
||||
#endif /* XCE_TESTING */
|
||||
|
||||
static int vtask_entry(vtask_t* task)
|
||||
{
|
||||
int rc;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue