Commit 689f2e4
committed
fix(admin): default-group-scoped leader probe + RFC-compliant 405
Address findings from PR #689 round-1 review:
- [Codex P1] Scope newAdminLeaderProbe to the **default Raft group**
via coordinate.IsLeader / coordinate.VerifyLeader instead of the
prior "any local runtime" loop. Admin write paths
(kv/sharded_coordinator.go, adapter/sqs_admin.go) all key off the
default group, so a node leading only a non-default group could
return 200 here while still rejecting admin writes -- breaking the
endpoint's stated load-balancer contract. Routing through the
coordinator keeps the healthz answer aligned with what the
AdminForward proxy and SQS admin write path treat as authoritative.
newAdminLeaderProbe(runtimes []*raftGroupRuntime) becomes
newAdminLeaderProbe(coordinate kv.Coordinator). The change drops
the per-runtime engine.VerifyLeader fan-out and the
adminLeaderProbeTimeout constant -- coordinate.VerifyLeader is the
same ReadIndex round-trip lease reads use, with the engine's own
bounded deadline, so an outer 2 s timeout is no longer needed.
- [Claude / Gemini] Add the RFC 7231 §6.5.5 Allow: GET, HEAD header
to every router-served 405 response (healthz, healthz/leader,
asset, SPA). Pulled the body shape into a writeMethodNotAllowed
helper so the four call sites stay uniform; load balancers and
synthetic-monitor tools now see the same Allow header the S3 and
DynamoDB /healthz/leader handlers already advertise. New
TestRouter_405_AllowHeader sweeps every 405-emitting path so a
future handler that bypasses the helper would regress this test.
- [Claude / Gemini] Drop the redundant rt.leader == nil check inside
serveLeaderHealth. dispatch() already short-circuits the nil case
to rt.notFound before this handler is ever invoked; the in-body
check was dead code that misled readers about the precondition.
Documented the precondition explicitly on the function.
- [Gemini] Rewrite the misleading "ordering before /admin/healthz"
comment in classify(). Both healthz paths are exact-match equality
checks; their relative order does not matter for correctness. The
load-bearing rule is that BOTH must run before the SPA prefix
branch -- now spelled out that way.
Self-review (CLAUDE.md 5 lenses):
1. Data loss -- None. Read-only handlers; no Raft proposals touched.
2. Concurrency -- The probe now serialises through the coordinator's
default-group view, which is the same path lease reads use.
Behaviour during leadership change is unchanged: VerifyLeader's
ReadIndex returns an error, the probe returns false, the LB
takes the node out of rotation.
3. Performance -- Cheaper than the prior per-runtime loop in the
common single-group case (one IsLeader / one VerifyLeader vs N
per-runtime Status checks plus M VerifyLeader calls).
4. Data consistency -- coordinate.VerifyLeader is the same ReadIndex
round-trip the lease-read path uses; the load balancer can now
key off the same liveness signal admin writes do.
5. Test coverage -- new TestRouter_405_AllowHeader. Existing six
/admin/healthz/leader tests still cover happy / 503 / HEAD /
POST / nil-probe / SPA-no-swallow. The redundant-nil-guard
removal is covered by TestRouter_HealthzLeader_NilProbeReturns404
(still passes via dispatch()'s nil check).
Body-text parity nit: the PR description's "identical responses to
S3 and DynamoDB" is technically true vs DynamoDB but not S3 (S3
omits the trailing newline; this admin path matches DynamoDB). Not
worth a behaviour change -- LBs key off status codes, not body
strings -- but worth noting in case a future PR aligns the three.1 parent 5f50223 commit 689f2e4
3 files changed
Lines changed: 89 additions & 39 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
150 | 150 | | |
151 | 151 | | |
152 | 152 | | |
153 | | - | |
154 | | - | |
155 | | - | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
156 | 158 | | |
157 | 159 | | |
158 | 160 | | |
| |||
214 | 216 | | |
215 | 217 | | |
216 | 218 | | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
217 | 237 | | |
218 | 238 | | |
219 | | - | |
| 239 | + | |
220 | 240 | | |
221 | 241 | | |
222 | 242 | | |
| |||
233 | 253 | | |
234 | 254 | | |
235 | 255 | | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
236 | 260 | | |
237 | 261 | | |
238 | | - | |
| 262 | + | |
239 | 263 | | |
240 | 264 | | |
241 | 265 | | |
242 | | - | |
| 266 | + | |
243 | 267 | | |
244 | 268 | | |
245 | 269 | | |
| |||
258 | 282 | | |
259 | 283 | | |
260 | 284 | | |
261 | | - | |
| 285 | + | |
262 | 286 | | |
263 | 287 | | |
264 | 288 | | |
| |||
335 | 359 | | |
336 | 360 | | |
337 | 361 | | |
338 | | - | |
| 362 | + | |
339 | 363 | | |
340 | 364 | | |
341 | 365 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
119 | 119 | | |
120 | 120 | | |
121 | 121 | | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
122 | 125 | | |
123 | 126 | | |
124 | 127 | | |
125 | 128 | | |
126 | 129 | | |
127 | 130 | | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
128 | 163 | | |
129 | 164 | | |
130 | 165 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
135 | 135 | | |
136 | 136 | | |
137 | 137 | | |
138 | | - | |
| 138 | + | |
139 | 139 | | |
140 | 140 | | |
141 | 141 | | |
142 | 142 | | |
143 | | - | |
144 | | - | |
145 | | - | |
146 | | - | |
147 | | - | |
148 | | - | |
149 | | - | |
150 | 143 | | |
151 | 144 | | |
152 | 145 | | |
153 | 146 | | |
154 | | - | |
| 147 | + | |
155 | 148 | | |
156 | 149 | | |
157 | 150 | | |
158 | | - | |
159 | | - | |
160 | | - | |
161 | | - | |
162 | | - | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
163 | 161 | | |
164 | | - | |
| 162 | + | |
165 | 163 | | |
166 | 164 | | |
167 | | - | |
168 | | - | |
| 165 | + | |
| 166 | + | |
169 | 167 | | |
170 | 168 | | |
171 | 169 | | |
172 | | - | |
173 | | - | |
174 | | - | |
175 | | - | |
176 | | - | |
177 | | - | |
178 | | - | |
179 | | - | |
180 | | - | |
181 | | - | |
182 | | - | |
183 | | - | |
184 | | - | |
| 170 | + | |
| 171 | + | |
185 | 172 | | |
186 | | - | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
187 | 178 | | |
188 | 179 | | |
189 | 180 | | |
| |||
0 commit comments