feat(raft-drive-async): offload requester-less config-push to slow lane (task 3.3)

push_config_transport_only spawns one thread per standby then joins them with a
CONF_PUSH_TIMEOUT_MS bounded wait — blocking the caller. On the requester-less
drive-thread paths (promotion + heartbeat convergence) that wait stalls the
io_worker. Route those through ha_config_push_offloadable, gated by
g_drive_async_configpush_offload (default OFF → inline, byte-for-byte legacy;
ON → slow lane, non-blocking).

Flag ON deep-copies the config bytes + sha into a lane ctx (caller keeps owning
and freeing its own buffer); a single cluster-wide single-flight guard
(ha_state_t.configpush_inflight scalar CAS + lane key=1) bounds it to one
config-push fan-out in flight; the in-flight flag is cleared on every terminal
path (two alloc failures, -EEXIST, hard submit error, lane completion). Send
body factored into ha_config_push_do_send.

Three requester-less drive-thread call sites converted: raft_cb_become_leader
(promotion), the HA_REPL_PUSH_CONFIG heartbeat case, and the direct-CTRL_PRIMARY
FSM promotion branch. The admin-upgrade barrier (push_config_to_standbys, has a
waiting requester) and join.c are untouched.

Lands DORMANT like tasks 3.1/3.2: the lane reads c->ha.standby_endpoints and
writes those borrowed standby endpoints, racing io_worker RDHUP teardown if run
off-thread (bug-1197 family). Flag OFF keeps push+teardown serialized on the
io_worker. Task 3.4 flips this ON together with the snapshot and peerctrl flags
after establishing endpoint-lifetime discipline.

Tests (controller suite EXIT=0): test_configpush_offload_runs_on_lane,
test_configpush_inline_when_flag_off, test_configpush_offload_dedups.
Adversarial cpp-review: no CRITICAL/HIGH/MEDIUM findings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S6fDCtXkkEgupu7rUah1y2
This commit is contained in:
Rongsong Shen 2026-06-26 16:05:54 +00:00
parent 6c0523b69b
commit bd02064ebc
5 changed files with 515 additions and 13 deletions

View file

@ -3472,3 +3472,17 @@
| 08:42 | Edited .kiro/specs/raft-drive-async/tasks.md | inline fix | ~41 |
| 08:42 | Edited .kiro/specs/raft-drive-async/tasks.md | modified completion() | ~830 |
| 08:42 | raft-drive-async 3.2: snapshot SlowLane offload (Part A, DORMANT flag-OFF) + trim cursor-guard (Part B, LIVE) | ha.c, ha.h, persist.c, test_ha_liveness.c, test_e2e_checkpoint.c | 196/0 ctrl tests, 0 new leaks, cpp-review GO; caught+fixed default-ON UAF (bug-1210) | ~62k |
| 08:49 | Edited src/controller/ha.h | expanded (+14 lines) | ~364 |
| 08:49 | Edited src/controller/ha.h | modified OFF() | ~351 |
| 08:50 | Edited src/controller/ha.c | modified ha_snapshot_offload_enabled() | ~513 |
| 08:51 | Edited src/controller/ha.c | added 10 condition(s) | ~2166 |
| 08:51 | Edited src/controller/ha.c | expanded (+10 lines) | ~152 |
| 08:51 | Edited src/controller/ha.c | 14→16 lines | ~228 |
| 08:52 | Edited src/controller/ha.c | modified XCE_TESTING() | ~179 |
| 08:52 | Edited src/controller/ha.c | expanded (+7 lines) | ~176 |
| 08:52 | Edited src/controller/ha.c | 14→16 lines | ~212 |
| 08:53 | Edited src/controller/testsuite/test_ha_liveness.c | added 3 condition(s) | ~2156 |
| 08:54 | Edited src/controller/testsuite/test_ha_liveness.c | 4→8 lines | ~113 |
| 08:57 | Edited src/controller/ha.c | modified XCE_TESTING() | ~115 |
| 09:05 | Edited .kiro/specs/raft-drive-async/tasks.md | inline fix | ~51 |
| 09:05 | raft-drive-async 3.3: requester-less config-push SlowLane offload (DORMANT flag-OFF), 3 drive-thread sites + deep-copy bytes ownership | ha.c, ha.h, test_ha_liveness.c | 3 tests pass, ctrl EXIT=0, cpp-review GO no CRIT/HIGH/MED | ~58k |