Skip to content

Clean up old generations that are building up in active long-running workflows - #415

Open
Thom Chiovoloni (thomcc-work) wants to merge 8 commits into
mainfrom
thomcc/exe-clean
Open

Thom Chiovoloni (thomcc-work) wants to merge 8 commits into
mainfrom
thomcc/exe-clean

Conversation

@thomcc-work

@thomcc-work Thom Chiovoloni (thomcc-work) commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Prune old execution generations from long-running workflows, including workflows that are still active.

Previously, continue_as_new bounded replay history but not stored history: old generations remained until the entire workflow was deleted. Background reconciliation now removes completed, non-current generations older than pg_durable.retention_days.

Depends on microsoft/duroxide-pg#32.

Changes

  • Integrate the provider’s cursor-based batch-pruning API into background maintenance, covering control, satellite, and nested-loop executions.
  • Preserve current and Running executions, workflow metadata, and current results.
  • Bound each slice to at most 1,000 scanned execution keys, including protected or ineligible rows, so scanning continues through retained history.
  • Use maintenance connections with server-side statement and lock deadlines rather than consuming the runtime’s connection pool.
  • Retry cancelled queries with smaller batches after rollback, allowing individually prunable generations to progress when their combined batch exceeds the deadline. Other failures and unprunable single generations are deferred without blocking later pages.
  • Read execution-history details and event counts in one snapshot, avoiding lookup errors when pruning runs concurrently.
  • Update worker readiness, test-runner integration, retention documentation, and upgrade guidance.

Retention and upgrade behavior

  • Historical generations use the existing age-based retention window, not a generation-count cap.
  • pg_durable.reconcile_interval = 0 also disables execution pruning.
  • The worker applies provider migrations before publishing readiness. The provider recovers missing completion timestamps from recorded terminal events; missing events retain NULL timestamps with a warning, while malformed history aborts migration with diagnostic keys.
  • Upgrade requires draining all old provider callers, including external clients and maintenance jobs—not only workers. Backfill can increase startup time and WAL volume.
  • No extension SQL upgrade is required for this feature; supported older df schemas remain compatible.
  • Pruning does not cap history within a single execution or reclaim completed child instances independently of their owning workflow.

Landing blocker: the provider remains pinned to immutable revision 7987089 with DONOTLAND. Replace it with an exact compatible released version once the upstream changes are published. Earlier pre-release builds used the same migration numbers with different bodies; updating their dependency alone does not reinstall those functions.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The unreleased provider dependency and deletion of active-workflow history require human review and upgrade/replay validation before landing.

1 open finding
What changed in this PR

Adds age-based cleanup of historical execution generations, including those belonging to active workflows, while preserving current and running executions.

Changes:

  • Adds bounded pruning with deadlines and failed-page recovery.
  • Makes execution-history inspection consistent during concurrent pruning.
  • Updates dependencies, readiness checks, tests, and retention documentation.
File Description
USER_GUIDE.md Documents pruning behavior and upgrade considerations.
tests/​e2e/​sql/​89_execution_pruning.sql Tests root, nested, and satellite workflow pruning.
src/​worker.rs Implements bounded pruning and regression tests.
src/​types.rs Updates retention documentation.
src/​monitoring.rs Reads execution details in one snapshot.
src/​lib.rs Updates readiness version and retention descriptions.
scripts/​test-e2e-local.sh Routes pruning tests to reconciliation configuration.
scripts/​test-e2e-docker.sh Skips the configuration-dependent pruning test.
docs/​upgrade-testing.md Documents migrations and release prerequisites.
Cargo.toml Updates runtime and provider dependencies.
Cargo.lock Records updated dependency resolutions.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread Cargo.toml Resolved

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The unreleased provider dependency adds startup backfill and destructive history pruning alongside runtime shutdown changes, requiring previous-binary upgrade/replay and PostgreSQL shutdown validation with the final dependency pair.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

@thomcc-work
Thom Chiovoloni (thomcc-work) marked this pull request as ready for review November 3, 2026 16:03
Also:

- Updated upgrade guidance for fully drained callers, malformed-history diagnostics, WAL/retention impact, and timestamp repair.
- Documented that databases using earlier pre-release migrations won’t automatically receive revised function bodies.
- Added a regression confirming protected generations advance the cursor without waiting on instance locks.
Compare snapshot inspection against the Client metadata API using tables created by the pinned provider's migrations and populated through provider operations. Document the existing migrated-schema coverage of pruning keys.

Ref: #415 review finding 415-1

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Explain that pruning holds candidate instance locks until commit and can briefly delay acknowledgements, particularly during the first post-backfill scans. Preserve the existing batch and timeout policies.

Ref: #415 review finding 415-2

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Distinguish the provider's ^0.1.32 requirement from pg_durable's deliberate =0.1.32 pin. Record that the combined release with PR 429 needs later runtime changes and coordinated exact pins with replay validation.

Ref: #415 review finding 415-3

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants