Repository navigation
Python: fix(workflow): finish in-flight checkpoint saves when a sibling step fails - #9644
Open
ShiYuan Xiong (hehe764) wants to merge 5 commits into
Open
ShiYuan Xiong (hehe764) wants to merge 5 commits into
ShiYuan Xiong (hehe764) wants to merge 5 commits into
Conversation
…fails A step that completed and emitted executor_completed before a sibling failed could have its per-step checkpoint save cancelled by run teardown. asyncio.gather cancels the completed step's task as soon as the sibling raises, and the failure-path task sweep cancelled the save task itself (the loop task factory tracks every task), so a storage whose save awaits I/O before writing lost the checkpoint. The latest checkpoint then held no trace of the finished step and a resumed run re-ran it and its side effects. Run the save as its own task, shield both awaits so a cancellation of the step task cannot reach it, and have the task sweep wait for in-flight saves instead of cancelling them. A completed step is now restored from the checkpoint whatever storage is used.
ShiYuan Xiong (hehe764)
requested review from
SergeyMenshykh,
Tao Chen (TaoChenOSU),
Eduard van Valkenburg (eavanvalkenburg),
Giles Odigwe (giles17),
Jose Alvarez (jpalvarezl),
Evan Mattson (moonbox3),
Roger Barreto (rogerbarreto),
sophia-ramsey and
westey (westey-m)
as code owners
October 23, 2026 12:18
ShiYuan Xiong (hehe764)
deployed
to
github-app-auth
October 23, 2026 12:18 — with
GitHub Actions
Active
Author
|
@microsoft-github-policy-service agree |
ShiYuan Xiong (hehe764)
deployed
to
github-app-auth
October 23, 2026 13:15 — with
GitHub Actions
Active
ShiYuan Xiong (hehe764)
deployed
to
github-app-auth
October 23, 2026 13:16 — with
GitHub Actions
Active
ShiYuan Xiong (hehe764)
deployed
to
github-app-auth
October 23, 2026 13:18 — with
GitHub Actions
Active
ShiYuan Xiong (hehe764)
deployed
to
github-app-auth
October 23, 2026 14:08 — with
GitHub Actions
Active
ShiYuan Xiong (hehe764)
deployed
to
github-app-auth
October 23, 2026 14:09 — with
GitHub Actions
Active
ShiYuan Xiong (hehe764)
deployed
to
github-app-auth
October 23, 2026 14:58 — with
GitHub Actions
Active
This branch was successfully deployed
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.
Motivation & Context
A functional workflow with checkpoint storage can lose the per-step checkpoint of a step that already completed when a parallel sibling step fails, so a resumed run re-runs the completed step and its side effects. Whether the checkpoint is lost depends on the storage implementation's await timing, not on user code. Fixes #9615 (analysis and approach proposed in the linked issue comment).
Description & Review Guide
What are the major changes?
asyncio.shield, so a cancellation of the step task during the framework's failure cleanup after a sibling raises cannot reach the save through the await.RunContexttracks in-flight per-step saves in a dedicated set;_cancel_workflow_tasksexpands protection through the task-parent map to include storage-created descendants, and drains these tasks rather than cancelling them.test_completed_parallel_step_is_checkpointed_when_sibling_failscovers inline asynchronous writes,asyncio.create_taskwrites, andasyncio.gatherwrites; all three resume without repeating the completed step.What is the impact of these changes?
What do you want reviewers to focus on?
_cancel_workflow_tasks: the sweep protects_checkpoint_save_tasksand their descendants from cancellation but still awaits them in its drain gather.Related Issue
Fixes #9615
AI Assistance
AI assistance details: AI assistance was used for the root-cause analysis, implementation, tests, and this PR description. All changes were reviewed, executed, and verified locally by the contributor (reproduction script, regression test red/green against unmodified
main, fulltests/workflow/suite on the merged head (14445d9e): 1282 passed, 6 skipped, 1 xfailed; ruff and pyright passed). The descendant-task regression failed for task/gather storage before this follow-up fix. The complete core suite was not rerun for the follow-up.Contribution Checklist