Commit 41c7f0f
authored
admin: AdminForward Phase 3 — register gRPC server + wire follower-side bridge (#648)
Phase 3 of Task #26 / AdminForward design 3.3. Closes the wiring loop
opened by #635 (leader-side dispatcher) and #644 (follower-side client +
handler integration): the admin HTTP DynamoHandler now hands
`ErrTablesNotLeader` writes off to the in-process `LeaderForwarder`, and
the leader-side gRPC `AdminForward` service is registered on every node
so the forwarded RPC actually lands somewhere.
## Summary
- **`admin.ServerDeps.Forwarder`** (3315bf4) — new optional field on
the high-level admin server composition surface. `admin.NewServer` calls
`WithLeaderForwarder` when set; nil leaves the existing 503 +
Retry-After:1 fallback untouched. Single-node / leader-only deployments
are unaffected.
- **`main_admin_forward.go`** (f3e529c) — production bridge between
`kv.GRPCConnCache` and the admin layer's typed `PBAdminForwardClient`
(via `pb.NewAdminForwardClient`). Includes `buildLeaderForwarder`,
`roleStoreFromFlags`, `adminForwardServerDeps`, and a
`readyForRegistration` gate.
- **Runtime wiring** (19f6b70) — `runtimeServerRunner.start()` now
creates `dynamoServer` BEFORE `startRaftServers`, so the leader-side
`ForwardServer` can use it as its `TablesSource`. `startRaftServers`
accepts the new `adminForwardServerDeps` bundle and delegates to
`registerAdminForwardServer`. `startServers` constructs a single
`*kv.GRPCConnCache` and forwards it (with the `Coordinator`) to
`startAdminFromFlags`, which in turn builds the production
`LeaderForwarder` via `buildAdminLeaderForwarder` and passes it through
`ServerDeps.Forwarder`.
## What is NOT in this PR
- Rolling-upgrade compatibility flag (criterion 5) — still deferred
behind a cluster-version bump.
- Election-period retry loop on the follower's bridge — the handler
returns 503 + Retry-After:1, the SPA / curl re-issues, and the bridge
dials again on the next attempt. Inline retry inside the handler would
just hide the latency from operators.
## Test plan
- [x] `go build ./...`
- [x] `go vet ./...`
- [x] `golangci-lint run` (main + admin packages: 0 issues)
- [x] `go test ./internal/admin/ -count=1 -race` — full admin suite
passes (existing 21 forward tests + 1 new
`TestServer_ServerDepsForwarderIsWired`)
- [x] `go test . -count=1 -race` — main package passes (4 new bridge /
role-store / readyForRegistration tests)
- [ ] `adapter` package times out at 240s on this branch AND on `main` —
pre-existing flake unrelated to this PR (verified by checking out main
and running the same suite)
- [ ] End-to-end smoke against a 3-node cluster — needs the local Jepsen
runner; blocked on the next PR or a manual run
## Acceptance criteria coverage
| # | Criterion | This PR |
|---|---|---|
| 1 | Leader direct write | ✓ (in main since #634) |
| 2 | Follower forwards transparently | ✓ — wiring complete; both
leader-side gRPC service AND follower-side bridge are now plumbed |
| 3 | Election-period 503 + retry | ✓ — handler still returns 503 +
Retry-After:1 when no leader is known; the SPA / client retries and the
next attempt re-dials |
| 4 | Leader demotes stale full role | ✓ (in main since #635) |
| 5 | Rolling-upgrade compat flag | ⏳ deferred (cluster-version bump) |
| 6 | `forwarded_from` in audit log | ✓ (in main since #635 — bridge now
stamps `--raftId` onto every forwarded request) |
## Self-review (5 lenses)
1. **Data loss**: No FSM / Raft / Pebble path changes; admin writes
still go through the same `AdminCreateTable` / `AdminDeleteTable` Raft
proposal once they reach the leader.
2. **Concurrency**: `runner.start()` reorder confirmed safe —
`startDynamoDBServer` only depends on `coordinate` + `shardStore`
(already constructed); raft TCP listeners are independent of the dynamo
HTTP listener. Worst case during the 100 ms-or-so reorder window is the
same "no leader yet" 503 the old order would have produced if a request
landed before raft converged.
3. **Performance**: One additional `&kv.GRPCConnCache{}` allocation per
process; one closure for the resolver. No hot-path changes.
4. **Data consistency**: Forwarded requests re-validate the principal at
the leader (criterion 4, already shipped); commit-ts ordering is
unchanged because the leader's `AdminCreateTable` path does its own
`HLC.Next`.
5. **Test coverage**: 4 new main-package tests + 1 new admin-package
server-level test. `TestServer_ServerDepsForwarderIsWired` is the
regression test for "future refactor drops the forwarder before it
reaches the dynamo handler" — exactly the failure mode the wiring change
in this PR introduces the risk of.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added leader-forwarding capability for admin requests sent to follower
nodes
* Implemented role-based access control for admin API operations
* Enhanced DynamoDB request routing to automatically direct operations
to leader nodes
* **Tests**
* Added comprehensive integration and unit tests validating
leader-forwarding paths
<!-- end of auto-generated comment: release notes by coderabbit.ai -->7 files changed
Lines changed: 508 additions & 17 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
42 | 50 | | |
43 | 51 | | |
44 | 52 | | |
| |||
110 | 118 | | |
111 | 119 | | |
112 | 120 | | |
113 | | - | |
| 121 | + | |
114 | 122 | | |
115 | 123 | | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
116 | 128 | | |
117 | 129 | | |
118 | 130 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
453 | 453 | | |
454 | 454 | | |
455 | 455 | | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
456 | 507 | | |
457 | 508 | | |
458 | 509 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
| 22 | + | |
22 | 23 | | |
23 | 24 | | |
24 | 25 | | |
| |||
680 | 681 | | |
681 | 682 | | |
682 | 683 | | |
| 684 | + | |
| 685 | + | |
| 686 | + | |
| 687 | + | |
| 688 | + | |
| 689 | + | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
| 702 | + | |
| 703 | + | |
| 704 | + | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
| 708 | + | |
| 709 | + | |
| 710 | + | |
| 711 | + | |
| 712 | + | |
| 713 | + | |
| 714 | + | |
| 715 | + | |
| 716 | + | |
| 717 | + | |
683 | 718 | | |
684 | 719 | | |
685 | 720 | | |
| |||
711 | 746 | | |
712 | 747 | | |
713 | 748 | | |
| 749 | + | |
714 | 750 | | |
715 | 751 | | |
716 | 752 | | |
| |||
720 | 756 | | |
721 | 757 | | |
722 | 758 | | |
723 | | - | |
| 759 | + | |
| 760 | + | |
| 761 | + | |
| 762 | + | |
| 763 | + | |
| 764 | + | |
| 765 | + | |
| 766 | + | |
724 | 767 | | |
725 | 768 | | |
726 | 769 | | |
| |||
975 | 1018 | | |
976 | 1019 | | |
977 | 1020 | | |
| 1021 | + | |
978 | 1022 | | |
| 1023 | + | |
979 | 1024 | | |
980 | 1025 | | |
981 | 1026 | | |
| |||
1005 | 1050 | | |
1006 | 1051 | | |
1007 | 1052 | | |
| 1053 | + | |
1008 | 1054 | | |
1009 | 1055 | | |
1010 | 1056 | | |
| |||
1255 | 1301 | | |
1256 | 1302 | | |
1257 | 1303 | | |
| 1304 | + | |
| 1305 | + | |
| 1306 | + | |
| 1307 | + | |
| 1308 | + | |
| 1309 | + | |
| 1310 | + | |
| 1311 | + | |
| 1312 | + | |
1258 | 1313 | | |
1259 | 1314 | | |
1260 | 1315 | | |
1261 | 1316 | | |
1262 | 1317 | | |
1263 | 1318 | | |
| 1319 | + | |
| 1320 | + | |
| 1321 | + | |
| 1322 | + | |
| 1323 | + | |
| 1324 | + | |
| 1325 | + | |
| 1326 | + | |
| 1327 | + | |
| 1328 | + | |
| 1329 | + | |
| 1330 | + | |
| 1331 | + | |
| 1332 | + | |
| 1333 | + | |
| 1334 | + | |
1264 | 1335 | | |
1265 | 1336 | | |
1266 | 1337 | | |
| |||
1275 | 1346 | | |
1276 | 1347 | | |
1277 | 1348 | | |
| 1349 | + | |
1278 | 1350 | | |
1279 | 1351 | | |
1280 | 1352 | | |
1281 | | - | |
1282 | | - | |
1283 | | - | |
1284 | | - | |
1285 | | - | |
1286 | 1353 | | |
1287 | 1354 | | |
1288 | 1355 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
68 | 68 | | |
69 | 69 | | |
70 | 70 | | |
71 | | - | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
72 | 80 | | |
73 | 81 | | |
74 | 82 | | |
| |||
109 | 117 | | |
110 | 118 | | |
111 | 119 | | |
112 | | - | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
113 | 125 | | |
114 | 126 | | |
115 | 127 | | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
116 | 154 | | |
117 | 155 | | |
118 | 156 | | |
| |||
346 | 384 | | |
347 | 385 | | |
348 | 386 | | |
| 387 | + | |
349 | 388 | | |
350 | 389 | | |
351 | 390 | | |
352 | 391 | | |
353 | 392 | | |
354 | 393 | | |
355 | 394 | | |
356 | | - | |
| 395 | + | |
357 | 396 | | |
358 | 397 | | |
359 | 398 | | |
| |||
393 | 432 | | |
394 | 433 | | |
395 | 434 | | |
396 | | - | |
| 435 | + | |
397 | 436 | | |
398 | 437 | | |
399 | 438 | | |
| |||
413 | 452 | | |
414 | 453 | | |
415 | 454 | | |
| 455 | + | |
416 | 456 | | |
417 | 457 | | |
418 | 458 | | |
| |||
0 commit comments