feat(bulk): release export/submit leases on graceful shutdown (#1531) - #1538
Merged
Merged
Conversation
On Ctrl-C the bulk export and submit workers now stop claiming, stop their job at a safe boundary, and release the lease, so another instance can claim it at once instead of waiting out the lease duration. - Export `release` (SQLite, PostgreSQL): in one fenced transaction the job returns to `accepted`, its attempt is refunded, and its progress and file rows are wiped. Returns whether the lease was still held; a zombie release is a no-op. - Submit `release` (SQLite, PostgreSQL, MongoDB, S3): returns whether it took effect. Re-queuing to `pending` matches the existing lapsed-lease reclaim path, which is already safe (idempotent re-walk, no attempt counter, artifacts published only with the terminal state). - Workers take a `CancellationToken` via `with_shutdown`. Export stops between batches or mid-read; submit reuses the cooperative abort stop. - hfs tracks the worker loops, cancels them on the shutdown signal, and waits up to HFS_WORKER_SHUTDOWN_TIMEOUT (default 20s) after the HTTP drain and before the audit/OTLP flush. - Contract tests per backend, plus worker-level shutdown tests. Co-Authored-By: Claude <noreply@anthropic.com>
…ses-on-shutdown # Conflicts: # crates/hfs/src/main.rs # crates/persistence/src/backends/sqlite/bulk_export.rs # crates/persistence/tests/mongodb_tests.rs # crates/persistence/tests/postgres_tests.rs
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1531.
Summary
On a graceful shutdown (SIGINT/SIGTERM), the bulk export and submit workers now stop claiming, stop their current job at a safe boundary, and release the lease. Another instance can claim the job at once instead of waiting out
HFS_BULK_{EXPORT,SUBMIT}_LEASE_DURATION.Export
release(SQLite, PostgreSQL)One fenced transaction (
worker_id+fencing_token, statusin-progress):accepted;attempts - 1, floored at 0), so rolling restarts no longer use upmax_attempts;releasenow returnsbool. A zombie release after a reclaim is a no-op.Submit
release(SQLite, PostgreSQL, MongoDB, S3, composite wrappers)Audited as the issue asked. A manifest released to
pendingends up in the same state as one whose lease lapsed, and that path is already safe:MAX-monotonic;_bulkrequests, leaves all 11,704 Provenance resources unsearchable (1 % cut), spends 1,551 s on its first attempt alone before retrying all 24 types, and writes a SQLite index nothing reads #1125 index-pending marker is set only after publication.So
releaseonly gains aboolreturn. The S3 version no longer swallows storage errors.Workers
DefaultExportWorker::with_shutdown: stops between batches, or mid-read/_typeFiltersearch where no part is open, then releases.DefaultSubmitWorker::with_shutdown: a bridge task trips the existing cooperative cancel (bulk-submit: Abort cannot stop an in-flight manifest, and a failed abort is invisible #968). The wind-down paths release when the stop came from shutdown and the lease is still held. A concurrent abort wins: the release is fenced onprocessing.hfs wiring
crates/hfs/src/worker_shutdown.rstracks the worker loops (TaskTracker+CancellationToken).serve()waits up toHFS_WORKER_SHUTDOWN_TIMEOUT(default 20 s), then records the audit shutdown and flushes audit/OTLP. Past the deadline, leases lapse as before.Shutdown signal
Hooked into
helios_observability::shutdown::signal()(SIGINT and SIGTERM, #907), so a rolling restart's SIGTERM releases leases too. The worker drain runs after the HTTP drain and before the audit/OTLP flush, including on a serve error.Tests
tests/bulk_submit/release_contract.rs, run on SQLite, Postgres, MongoDB and S3: release re-queues; zombie release, double release and release-after-abort are no-ops.worker_shutdownunit tests.Verified locally: persistence lib tests (sqlite, s3),
sqlite_testsand the SQLite bulk-submit suites, the Postgresbulk/exportand Mongobulk_submitfiltered suites, hfs tests, and clippy with the CI flags.🤖 Generated with Claude Code