Order flow-run heartbeats with state transitions - #22946
Conversation
Merging this PR will not alter performance
Comparing Footnotes
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e024e4fa15
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "Flow run in terminal state, stopping heartbeat" | ||
| ) | ||
| return | ||
| _enqueue_prepared_event(prepared) |
There was a problem hiding this comment.
Await heartbeat delivery before terminal requests
When the events worker is busy or reconnecting, _enqueue_prepared_event only places the heartbeat in QueueService via put_nowait; releasing this gate therefore allows the terminal state HTTP request to be processed while the heartbeat is still queued for network delivery. If the server observes Completed first and the delayed heartbeat afterward, the documented proactive zombie-flow pattern can clear its bucket on completion and then open a new bucket from the late heartbeat, causing alerts or crash actions against an already-completed run. Gate the request on an acknowledgement/checkpoint of actual heartbeat delivery rather than only its in-memory enqueue.
AGENTS.md reference: src/prefect/AGENTS.md:L23-L23
Useful? React with 👍 / 👎.
e024e4f to
7b0f7c5
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7b0f7c5ebe
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| from prefect.utilities.engine import ( | ||
| capture_sigterm, | ||
| link_state_to_flow_run_result, | ||
| propose_state, | ||
| propose_state_sync, | ||
| resolve_to_final_result, | ||
| ) |
There was a problem hiding this comment.
Preserve the public state-proposal aliases
Removing the propose_state and propose_state_sync imports also removes those non-underscored attributes from prefect.flow_engine, so downstream imports or patches now raise AttributeError. This already causes all eight TestFlowRunNameSetBeforeRunningEvent cases to fail at tests/test_flow_engine.py:116 and :133; keep compatibility aliases while routing engine internals through the new proposer wrappers.
AGENTS.md reference: src/prefect/AGENTS.md:L5-L7
Useful? React with 👍 / 👎.
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
7b0f7c5 to
79a319e
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 79a319e2b9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| with CancelScope(shield=True): | ||
| await run_sync_in_anyio_worker_thread( | ||
| self._gate.acquire, | ||
| ) |
There was a problem hiding this comment.
Make async lock ownership cancellation-safe
When an async flow task is cancelled via asyncio.Task.cancel() while this worker call is waiting behind an in-flight heartbeat enqueue, the AnyIO CancelScope does not defer that direct asyncio cancellation: the coroutine unwinds with acquired == False, but the worker continues and can later acquire _gate with no code left to release it. Subsequent heartbeat admission or session.aclose() can then hang indefinitely, so the ownership handoff must remain observable and release the lock even after direct task cancellation.
AGENTS.md reference: src/prefect/AGENTS.md:L23-L25
Useful? React with 👍 / 👎.
closes #21932
Depends on #22948
This PR orders flow-run heartbeat admission with server-authoritative state requests, preventing a heartbeat from being enqueued after the server accepts a terminal transition.
Details
WAITand accepted nonfinal responses.Supersedes #22897 and carries forward Devin's initial work.
Checklist
<link to issue>"mint.json.