Commit 80f1c86
committed
feat(sqs): live-queue reaper enumerates partitioned keyspace (Phase 3.D PR 6b)
Follow-up to PR 6a (#735). The tombstone-driven reaper now sweeps
partitioned data / vis / byage / dedup / group records on
DeleteQueue / PurgeQueue, but the live-queue retention reaper
still walked only the legacy keyspace, so:
- retention-expired messages on partitioned queues leaked their
data / vis / byage / group rows forever (reapQueue's byage
walk used sqsMsgByAgePrefixAllGenerations only),
- expired dedup records on partitioned FIFO queues leaked
forever (reapExpiredDedup's prefix scan used SqsMsgDedupPrefix
only — empty for partitioned queues, since
sqsMsgDedupKeyDispatch routes their writes under
SqsPartitionedMsgDedupPrefix).
Closes the live-queue half of the Codex P2 from PR #732 round 0
("Reap partitioned dedup records to prevent key growth"); PR 6a
covered the tombstoned-cohort half.
Scope (the second slice of §11 PR 6 from the split-queue-FIFO
design doc):
- reapQueue: legacy byage walk extracted as reapQueueLegacy,
behaviour byte-identical to pre-PR-6b for non-partitioned
queues. Adds a new reapQueuePartition step that runs once per
partition for PartitionCount > 1 queues. Each partition gets
its own per-partition budget per the §6 design ("partitions ×
budget per cycle"); a 32-partition queue thus allows up to 32
× sqsReaperPerQueueBudget records per tick, comfortably
within the 30s reaper interval.
- reapPartitionedPage: partitioned twin of reapPage. Same
live-vs-orphan classification (parsed.SendTimestampMs >
cutoff under the live gen, unconditional reap under older
gens, defensive skip on parsed.Generation > currentGen) but
parses each entry with parseSqsPartitionedMsgByAgeKey and
routes the dispatch through reapOneRecordPartitioned.
- classifyPartitionedByAgeEntry: helper extracted from
reapPartitionedPage so the loop body stays under the cyclop
ceiling. Returns (parsedKey, reapable bool).
- reapExpiredDedup: now takes *sqsQueueMeta and routes by
PartitionCount. Legacy meta (PartitionCount <= 1) →
reapExpiredDedupLegacy (byte-identical to pre-PR-6b walk).
Partitioned meta (PartitionCount > 1) →
reapExpiredDedupPartitioned (NEW), which iterates each
partition's partitioned dedup prefix under its own
per-partition budget and uses the existing reapDedupPage to
apply the value-based ExpiresAtMillis filter.
Caller audit:
- reapQueue: one production caller (reapAllQueues line 85).
No signature change. Behaviour for non-partitioned queues
byte-identical; partitioned queues get the additional
per-partition pass.
- reapExpiredDedup: signature changed to take *sqsQueueMeta.
One production caller (reapAllQueues line 88), updated. No
test files invoked this helper directly. Legacy meta
routes to the byte-identical legacy walk; partitioned routes
to the new walk.
- reapQueueLegacy / reapQueuePartition /
reapExpiredDedupLegacy / reapExpiredDedupPartitioned /
classifyPartitionedByAgeEntry: each has exactly one caller in
the new live-queue reap path.
- reapOneRecordPartitioned: existing helper from PR 6a.
Previous caller was reapDeadByAgePartitionPage (tombstone
path); now also called from reapPartitionedPage (live-queue
path). Same dispatch semantics — synthetic meta carrying
PartitionCount > 1 to flip the dispatch helper branch.
Tests:
- New TestSQSServer_PartitionedFIFO_LiveQueueDedupReaperPartitions
(wire-level): create a 4-partition FIFO queue, send across 6
distinct groups, backdate every partitioned dedup record's
ExpiresAtMillis, run reapAllQueues, assert every partitioned
dedup row across [0, 4) is gone. Pre-PR-6b reaper would have
left every row in place — the test fails on the legacy code
path.
Self-review (CLAUDE.md):
1. Data loss — Closes the live-queue dedup leak; closes the
partitioned retention-expired-message leak. Legacy queues
unchanged: reapQueue, reapExpiredDedup, byage walks, and
dispatch helpers all keep their byte-identical pre-PR-6b
paths for PartitionCount <= 1.
2. Concurrency / distributed failures — Reaper still runs only
on the leader. Each partition's pass is sequential; per-
partition budget bounds the pass. Existing OCC dispatch
semantics on each per-record reap unchanged.
3. Performance — Per-tick partitioned-queue cost grows from
O(1 walk) to O(partition_count walks) on byage AND dedup.
Each partition bounded by sqsReaperPerQueueBudget. 30s tick
interval comfortably absorbs 32-partition × per-queue
budget per design.
4. Data consistency — Live-vs-orphan classification on
partitioned byage mirrors the legacy branch exactly
(reapPage / reapPartitionedPage share the rules through
classifyPartitionedByAgeEntry). PartitionCount immutability
means the meta-driven iteration bound matches the on-disk
keys for any cohort.
5. Test coverage — One new wire-level integration test for
the partitioned dedup walk; the partitioned byage walk
reuses parsing / dispatch helpers already tested by PR 6a's
tombstone-reap integration test.1 parent f489669 commit 80f1c86
2 files changed
Lines changed: 309 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
| |||
648 | 649 | | |
649 | 650 | | |
650 | 651 | | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
| 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 | + | |
| 718 | + | |
| 719 | + | |
| 720 | + | |
| 721 | + | |
| 722 | + | |
| 723 | + | |
| 724 | + | |
| 725 | + | |
| 726 | + | |
| 727 | + | |
| 728 | + | |
| 729 | + | |
| 730 | + | |
| 731 | + | |
| 732 | + | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
| 736 | + | |
| 737 | + | |
| 738 | + | |
| 739 | + | |
| 740 | + | |
| 741 | + | |
| 742 | + | |
| 743 | + | |
| 744 | + | |
| 745 | + | |
| 746 | + | |
| 747 | + | |
| 748 | + | |
| 749 | + | |
| 750 | + | |
| 751 | + | |
| 752 | + | |
| 753 | + | |
| 754 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
85 | 85 | | |
86 | 86 | | |
87 | 87 | | |
88 | | - | |
| 88 | + | |
89 | 89 | | |
90 | 90 | | |
91 | 91 | | |
| |||
425 | 425 | | |
426 | 426 | | |
427 | 427 | | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
428 | 461 | | |
429 | 462 | | |
430 | 463 | | |
| |||
438 | 471 | | |
439 | 472 | | |
440 | 473 | | |
441 | | - | |
| 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 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
442 | 526 | | |
443 | 527 | | |
444 | 528 | | |
| |||
454 | 538 | | |
455 | 539 | | |
456 | 540 | | |
| 541 | + | |
| 542 | + | |
| 543 | + | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
457 | 592 | | |
458 | 593 | | |
459 | 594 | | |
| |||
593 | 728 | | |
594 | 729 | | |
595 | 730 | | |
596 | | - | |
| 731 | + | |
| 732 | + | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
| 736 | + | |
| 737 | + | |
| 738 | + | |
| 739 | + | |
| 740 | + | |
| 741 | + | |
| 742 | + | |
| 743 | + | |
| 744 | + | |
| 745 | + | |
| 746 | + | |
| 747 | + | |
| 748 | + | |
597 | 749 | | |
598 | 750 | | |
599 | 751 | | |
| |||
625 | 777 | | |
626 | 778 | | |
627 | 779 | | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
| 808 | + | |
| 809 | + | |
| 810 | + | |
| 811 | + | |
| 812 | + | |
| 813 | + | |
| 814 | + | |
| 815 | + | |
| 816 | + | |
| 817 | + | |
| 818 | + | |
| 819 | + | |
| 820 | + | |
| 821 | + | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
| 825 | + | |
| 826 | + | |
| 827 | + | |
| 828 | + | |
| 829 | + | |
628 | 830 | | |
629 | 831 | | |
630 | 832 | | |
| |||
0 commit comments