You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
admin: integrate LeaderForwarder into dynamo handler (Task #26 phase 2)
Wire the follower-side forwarder from phase 1 into the dynamo HTTP
handler so writes hitting a follower transparently dispatch to the
leader. Acceptance criteria 2 + 3 from design Section 3.3.2.
Changes:
- DynamoHandler gains a forwarder field plus
WithLeaderForwarder option. nil keeps the previous "503
leader_unavailable" behaviour, so a build that ships only the
leader can still deploy unchanged.
- handleCreate / handleDelete catch ErrTablesNotLeader from the
source and route to the forwarder. The principal already in
context flows through to the leader's audit log unchanged.
- writeForwardResult re-emits the leader's structured response
verbatim — status, payload, and content-type all come from the
gRPC response so a forwarded request looks identical to a
leader-direct call from the SPA's perspective.
- writeForwardFailure handles the two non-success paths:
ErrLeaderUnavailable (election in flight, criterion 3) and
generic gRPC transport errors. Both produce 503 + Retry-After: 1
so the SPA's retry policy is uniform regardless of where in the
chain the 503 came from. ErrLeaderUnavailable is NOT logged as
an error since elections are routine; transport errors are
logged at LevelError so operators can investigate.
- A 503 surfacing via the leader's structured response (e.g.,
leader stepped down mid-request) also gets Retry-After: 1
added on the way out so the wire contract is the same.
Tests cover criteria 2 (transparent forwarding for both create
and delete), 3 (election-period 503 + Retry-After), the
leader-direct error pass-through (409 conflict), the no-forwarder
fallback, and confirm the role / body validations short-circuit
*before* the forwarder is invoked. Stub LeaderForwarder + a
not-leader source make the tests deterministic without spinning
up a real Raft cluster.
0 commit comments