[Python] Isolate async work by key and window - #39996
Draft
bvolpato wants to merge 3 commits into
Draft
Conversation
Contributor
Author
|
Run Python_ML PreCommit 3.12 |
Contributor
Author
|
Run Python_ML PreCommit 3.10 |
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.
AsyncWrappertracks local futures by value (orid_fnresult), while runner state and timers are scoped to a key and window. For inputs('key1', 7)and('key2', 7), the second key can consume the first key's result and clear its own state without running its input. Equal identifiers across windows have the same problem. Timer cleanup can also cancel work belonging to another window of the same key.Track futures by
(encoded_key, window, identifier)and pass the window through scheduling, timer callbacks, and retries. The key uses the existing bag-state key coder: its encoded identity survives state decoding, including NaN keys, and distinguishes numeric keys that compare equal in Python, such as-0.0and0.0. Cleanup only removes orphaned work from the current encoded key and window. The persisted bag-state format stays unchanged.Testing
From
sdks/python, with the SDK and test dependencies installed:All 48 tests and 10 subtests pass on Python 3.12.
The cases exercise both the thread-pool and asyncio implementations: equal values and custom IDs across keys/windows, cleanup preserving another window's pending and completed work, and timer-driven rescheduling. The four cross-key regression cases fail against the upstream implementation. Additional state-coder roundtrip cases cover NaN completion, signed-zero and mixed numeric-key separation, and cancellation preserving another encoded key's work. Those cases fail with raw Python keys in the tracking map.
YAPF 0.43.0, Ruff 0.15.22, and
git diff --checkpass for the changed files. Validation uses the actual wrapper with state/timer doubles, including the real bag-state coder for the numeric-key cases; no end-to-end runner test was added.Downsides
Each local tracking entry now includes encoded key bytes and its window. Inputs with matching identifiers in different keys or windows execute independently and can occupy separate buffer slots. The configured buffer limit is unchanged.
CHANGES.mdwith the behavior change.