Repository navigation
Record completed_at for ContinuedAsNew executions - #32
Thom Chiovoloni (thomcc-work) wants to merge 9 commits into
Conversation
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
The production data backfill and replacement of a critical acknowledgement function warrant the planned manual testing and human review.
Review effort: Balanced
Findings: None
What changed in this PR
Records completion timestamps for continued-as-new executions, enabling age-based pruning of older generations.
Changes:
- Updates acknowledgement logic and backfills recoverable timestamps.
- Adds regression coverage for migration and pruning behavior.
- Documents migration behavior and operational guidance.
| File | Description |
|---|---|
migrations/0024_continue_as_new_completed_at.sql |
Updates and backfills completion timestamps. |
migrations/0024_diff.md |
Documents the migration delta. |
migrations/README.md |
Adds upgrade and pruning guidance. |
src/migrations.rs |
Refreshes the migration embedding marker. |
tests/regression_tests.rs |
Tests fresh installs, upgrades, and pruning. |
CHANGELOG.md |
Records the fix under Unreleased. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
e7773b3 to
97d0ac4
Compare
There was a problem hiding this comment.
Heads-up from #44, now tracked in #46.
#44 also adds migration 0026 and replaces ack_orchestration_item. It adds an advisory lock, a token recheck and a row-count check, to fix the double processing in #29. This PR's 0024 rebuilds ack_orchestration_item from the 0020 body. If this PR merges after #44 as it is, it silently reverts that fix.
Whichever PR merges second needs to:
- renumber its migration;
- carry both changes in its copy of
ack_orchestration_item; - run
cargo test --test deadlocks --test orchestration_ack_lease_tests.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rom age-filtered bulk deletion Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
c89f754 to
3ed62ed
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Batched pruning and atomic deletion acquire instance locks in inconsistent orders, risking deadlocks during concurrent multi-instance operations that existing single-instance tests cannot expose.
1 open issue
2 resolved since last review
Review effort: Balanced
There was a problem hiding this comment.
🔵 Needs a closer look
The retention backfill and destructive-operation lock-order changes require PostgreSQL-backed upgrade, replay/pruning, and concurrency validation that was unavailable in this review.
No open issues 🎉
2 resolved since last review
Review effort: Balanced
Precheck eligibility without changing scanned-key bounds or cursors, then retain the locked eligibility recheck. Exercise the hostile search_path with an eligible row and verify protected instances do not require locks. Ref: #32 (32-S1, 32-S3) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep the backfill set-based on success and preserve SQLSTATE while adding the failing history key on JSONB decode errors. Verify atomic rollback, valid upgrades, and a schema built entirely from the pre-0027 migration prefix. Ref: #32 (backfill diagnostics and upgrade-fixture review notes) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Require draining all provider callers, pause retention during upgrades, and describe the one-time deletion wave and backfill/WAL cost. Document an explicit timestamp-only repair after draining, preserve the migration ledger, and classify existing-procedure fixes under Fixed. Ref: #32 (32-M1, 32-S2, changelog review note) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Start one new ApplyAll process first and wait for provider initialization to complete before restarting the remaining upgraded callers. Keep migrations numbered 0027/0028 pending merge-order coordination. Ref: #32 (upgrade-startup review nit) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>


Summary
Record
completed_atforContinuedAsNewexecutions so age-based retention can remove old generations of long-running workflows. Previously, those timestamps remained NULL, leaving continued executions ineligible for age-based pruning.This also adds a paginated SQL pruning API and coordinates locking across pruning and deletion operations to protect live executions during concurrent maintenance.
Changes
Completion timestamps — migration
0027OrchestrationContinuedAsNewhistory event, using its original timestamp rather than the upgrade time.Batched pruning — migration
0028prune_executions_batch, which scans a primary-key-ordered page of 1–1,000 execution keys and returns a continuation cursor and scanned/deleted counts.public.Each batch is atomic. The limit bounds scanned execution keys, not the number of history events deleted.
Bulk deletion and compatibility
Upgrade notes
This requires a fully drained upgrade, not a rolling upgrade with old and new provider binaries together.
Stopping only workers is insufficient: old age-based deletion code can delete pending continuations after their completion timestamps are populated.
Expect a one-time wave of age-based deletions of old continue-as-new generations when retention resumes. Backfill time and WAL volume grow with the number of continue-as-new rows to repair; large histories can further increase backfill time. The backfill itself does not delete executions or history.
If the upgrade was not fully drained, an old acknowledgement can write a NULL completion timestamp after the backfill. Drain all callers first, then use the explicit timestamp repair procedure. Re-running the backfill while old calls remain in flight does not close that race; do not delete migration ledger rows to force a rerun.