Commit bc6dbd4
authored
docs(sqs): proposals for Phase 3.C (throttling) + 3.D (split-queue FIFO) (#664)
## Summary
**Docs-only PR.** Two design proposals for the remaining Phase 3 SQS
items per
[`docs/design/2026_04_24_proposed_sqs_compatible_adapter.md`](https://github.com/bootjp/elastickv/blob/main/docs/design/2026_04_24_proposed_sqs_compatible_adapter.md)
Section 14 (Phase 3 bullets). Both items were explicitly called out as
needing separate design docs before any implementation work; this PR
lands those proposals so the implementation PRs have a reviewed
architecture to build on.
### 3.C — Per-queue throttling and tenant fairness
([proposal](docs/design/2026_04_26_proposed_sqs_per_queue_throttling.md))
Per-queue token-bucket throttling configured on queue meta (no separate
keyspace), evaluated at the SQS adapter layer on the leader (no Raft per
request), surfaced as the AWS `Throttling` error envelope so SDK
retry/backoff just works.
Key decisions:
- **Default-off**. Existing queues are unaffected; operators opt in per
queue via `SetQueueAttributes`.
- **Per-action buckets** (Send / Receive / Default) so a slow consumer
cannot pin the producer.
- **Per-leader buckets, no replication**. Worst case on failover: one
extra burst on the new leader. Acceptable per AWS-equivalent behaviour
at region failover boundaries; replicating would cost a Raft commit per
`SendMessage`.
- **Batch verbs charge by entry count**, not call count, with
all-or-nothing rejection (matches AWS).
- **Admin-only configuration plane**. Standard SQS clients see
`InvalidAttributeName` on the `Throttle*` attributes (matches AWS
behaviour for unknown attributes); the data-plane enforcement runs for
everyone.
### 3.D — Split-queue FIFO (high-throughput FIFO)
([proposal](docs/design/2026_04_26_proposed_sqs_split_queue_fifo.md))
Per-`MessageGroupId` hash partitioning across multiple Raft groups,
mirroring AWS High Throughput FIFO. Within-group ordering preserved;
across-group throughput scales with the partition count.
Key decisions:
- **Existing single-partition FIFO queues stay byte-identical**
(`PartitionCount = 0` path is the legacy layout; no migration runs
implicitly).
- **Power-of-two partition counts only** (1, 2, 4, 8, 16, 32) so the
routing step is `hash & (N-1)` and future offline rebuilds stay
tractable.
- **Partition count is immutable after first SendMessage**. Live
re-partitioning would break ordering for in-flight messages of every
group whose hash bucket changed; out of scope.
- **Multi-PR rollout plan** with an explicit "gate of no return" called
out at PR 5 (the data-plane PR). PRs 1–4 are reversible no-ops on data
layout; once a partitioned FIFO holds real data, rollback means draining
and recreating the queue.
- **FNV-1a hash** (deterministic across processes / Go versions /
architectures). Risk of attacker-controlled `MessageGroupId` pinning all
traffic to one partition is documented and accepted (the feature is for
cooperative operators).
## Test plan
- [x] Markdown renders correctly on GitHub (manually previewed).
- [x] Cross-references resolve (the partial-doc rename in PR #659 is in
flight; both proposals reference the partial filename — they will
resolve once #659 merges, otherwise resolve to the current `_proposed_`
filename for a 1-character mismatch that is fine to leave for now).
- [x] No code changes; CI is irrelevant beyond the markdown lint pass.
## Self-review
This is a docs-only PR; the 5-lens self-review collapses to:
1. **Data loss / Concurrency / Performance / Consistency** — N/A, no
code touched.
2. **Test coverage** — N/A, no code touched. The proposals themselves
include a Testing Strategy section (§6 / §9) so the implementation PRs
have explicit acceptance criteria.
## Stacking
This PR is **independent** of #650, #659, and #662. Branched from
current `main`. Merge whenever ready — landing the proposal docs early
lets reviewers comment on the architecture before the implementation PRs
go up.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Added detailed designs for optional per-queue token-bucket throttling
(rules, batch semantics, AWS-shaped Throttling errors with Retry-After,
metrics, rollout default-off) and for HT‑FIFO “split-queue” partitioning
(routing, immutability, gating/rollout).
* **New Features**
* Optional queue-level send/receive throttling with batch-aware charging
and Retry-After; HT‑FIFO partitioning with deterministic partition
routing and immutable partition attributes.
* **Tests**
* Extensive unit and integration tests for throttling, HT‑FIFO
partitioning, attribute validation, immutability, idempotency, and cache
invalidation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->15 files changed
Lines changed: 4304 additions & 39 deletions
File tree
- adapter
- docs/design
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
8 | 9 | | |
9 | 10 | | |
10 | 11 | | |
| |||
55 | 56 | | |
56 | 57 | | |
57 | 58 | | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
58 | 64 | | |
59 | 65 | | |
60 | 66 | | |
| |||
76 | 82 | | |
77 | 83 | | |
78 | 84 | | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
79 | 90 | | |
80 | 91 | | |
81 | 92 | | |
| |||
98 | 109 | | |
99 | 110 | | |
100 | 111 | | |
| 112 | + | |
101 | 113 | | |
102 | 114 | | |
103 | 115 | | |
| |||
131 | 143 | | |
132 | 144 | | |
133 | 145 | | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
134 | 150 | | |
135 | 151 | | |
136 | 152 | | |
| |||
302 | 318 | | |
303 | 319 | | |
304 | 320 | | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
136 | 136 | | |
137 | 137 | | |
138 | 138 | | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
139 | 162 | | |
140 | 163 | | |
141 | 164 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
294 | 294 | | |
295 | 295 | | |
296 | 296 | | |
297 | | - | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
298 | 302 | | |
299 | 303 | | |
300 | 304 | | |
301 | | - | |
| 305 | + | |
302 | 306 | | |
303 | 307 | | |
304 | 308 | | |
305 | 309 | | |
306 | | - | |
| 310 | + | |
307 | 311 | | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
308 | 327 | | |
309 | 328 | | |
310 | 329 | | |
311 | | - | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
312 | 334 | | |
313 | 335 | | |
314 | 336 | | |
315 | | - | |
| 337 | + | |
316 | 338 | | |
317 | 339 | | |
318 | 340 | | |
319 | | - | |
| 341 | + | |
320 | 342 | | |
321 | 343 | | |
322 | 344 | | |
323 | 345 | | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
324 | 358 | | |
325 | 359 | | |
326 | 360 | | |
| |||
530 | 564 | | |
531 | 565 | | |
532 | 566 | | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
533 | 574 | | |
534 | 575 | | |
535 | 576 | | |
| |||
1106 | 1147 | | |
1107 | 1148 | | |
1108 | 1149 | | |
| 1150 | + | |
| 1151 | + | |
| 1152 | + | |
1109 | 1153 | | |
1110 | 1154 | | |
1111 | 1155 | | |
| |||
1258 | 1302 | | |
1259 | 1303 | | |
1260 | 1304 | | |
| 1305 | + | |
| 1306 | + | |
| 1307 | + | |
1261 | 1308 | | |
1262 | 1309 | | |
1263 | 1310 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
94 | 94 | | |
95 | 95 | | |
96 | 96 | | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
97 | 100 | | |
98 | 101 | | |
99 | 102 | | |
| |||
453 | 456 | | |
454 | 457 | | |
455 | 458 | | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
456 | 462 | | |
457 | 463 | | |
458 | 464 | | |
| |||
519 | 525 | | |
520 | 526 | | |
521 | 527 | | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
522 | 531 | | |
523 | 532 | | |
524 | 533 | | |
| |||
0 commit comments