Add highly available background task delivery - #22609
Draft
zzstoatzz wants to merge 12 commits into
Draft
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
Merging this PR will not alter performance
Comparing Footnotes
|
zzstoatzz
force-pushed
the
codex/docket-background-task-ha
branch
from
August 4, 2026 20:38
cc19508 to
6fa611d
Compare
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 #21218
this PR replaces process-local background-task delivery with a Docket queue so any Prefect API replica can deliver a deferred task run to any matching TaskWorker.
Implementation
SCHEDULEDtransition.Task.map(..., deferred=True)creates runs through one shared client with bounded concurrency (2) instead of opening a client and submitting each mapped run sequentially.The Prefect adapter is 189 lines and has no Redis client access or Lua. Those details live behind the proposed Docket queue API in chrisguidry/docket#451.
HA and delivery guarantees
Shared Redis is the delivery source of truth, consistent with Prefect existing Docket-backed server services. Publication is awaited before the state transition returns. Claims are at least once: an API crash cannot delete an unacknowledged task, and duplicate execution remains possible if a process fails after the downstream worker accepts work but before Redis records the acknowledgement.
The cross-process reproduction starts replicas subscribed to matching and non-matching task keys, lets replica A claim a run, hard-terminates A, and starts replica B. Replica B reclaims and acknowledges the same task-run delivery; the unrelated-key replica never claims it.
Self-hosted HA uses the existing Docket Redis configuration. There is no separate background-task HA procedure.
Results and Cloud compatibility
Docket owns delivery only. Prefect still owns task execution, task-run state, parameter persistence, return-value persistence, events, and
PrefectDistributedFuture.result(). Docket results are not used as Prefect task results.The TaskWorker WebSocket protocol, task-run REST/state schemas,
Task.delay, and result storage are unchanged. The mapped-submission optimization uses the existing task-run create endpoint, so this branch does not require a Prefect Cloud backend change.The branch is temporarily pinned through an immutable source archive to Docket commit
6d05b3a415b4849e3f3464544cf45cbec36c3f5e. Before merge, that pin should become the released version containing Docket #451. Queue consumers require Redis 6.2+ forXAUTOCLAIM.Performance
Controlled OSS setup after rebasing onto current main: clean PostgreSQL databases, one API server, two TaskWorkers (
limit=100each), warning-level logging, and 2,000 mapped deferred no-op tasks with persisted parameters/results. Main and this branch used the same Python 3.12 environment, machine, and harness.f3e3cd5a01)6fa611dad7)Against current main this PR reduces wall time 27.6% and raises end-to-end throughput 38.1%. All 2,000 runs completed without failure, and persisted results sampled at indices 0, 1,000, and 1,999 were correct.
An earlier one-worker paced comparison was not a win: bounded concurrent submission can outrun one worker, and the paced comparison was approximately 3% slower than main. The improvement appears when workers can consume the faster documented mapped-submission path; the single-worker caveat is intentional and should remain visible in review.
The CLI benchmark invokes syncing
uv run --directory …for every sample. In a controlled Python 3.12 comparison (30 interleavedprefect --versionsamples each), main's released Docket measured 478.1ms mean / 474.3ms median, the source-archive pin measured 695.3ms / 716.4ms, and the identical PR commit with the identical Docket commit packaged as a local wheel measured 471.7ms / 467.0ms.uv -vvresolved the archive environment on each invocation in about 236ms versus 4ms for both wheel environments. The failing shards therefore measure direct-reference resolution overhead, not installed Prefect startup; Docket is absent from startupsys.modules, andpyinstrumenthas no Docket startup frames. Replacing the temporary archive pin with the released wheel removes that overhead.Breaking changes
This removes
prefect.server.task_queue, including the technically publicTaskQueueandMultiQueueclasses and per-keyconfigure_task_keyhelper. They represented the process-local implementation that caused #21218 and are not retained as a compatibility facade. This is suitable for a minor release, but it is a real import break.The existing global scheduled/retry queue-size settings remain and now apply to durable Docket topics.
server.tasks.scheduling.delivery_visibility_timeoutis additive.Validation
uvresolving the temporary archive reference; replacing only that reference with a wheel matches main./nvm.shin this environment;npm run checkpasses directly with the installed Node 22 toolchain.f3e3cd5a01. The 65 intervening commits and the Prefect 3.8.1 release do not replace background-task delivery; the future-timeout and WebSocket User-Agent changes compose with this implementation. Docket main and its latest 0.23.1 release are unchanged since this branch's base.