Repository navigation
fix(state-manager): stop redis lock handoffs from stalling events until the lock expires - #7534
Open
benedikt-bartscher wants to merge 17 commits into
Open
benedikt-bartscher wants to merge 17 commits into
benedikt-bartscher wants to merge 17 commits into
Conversation
…ffs, keep a lease's lock while its state is in use and wake waiters a release missed
Contributor
|
Merging this PR will not alter performance
|
…thin each use's lock expiration, and report a failed renewal
…tion interrupts it
…ed state changes hands
…of asyncio.wait_for, which can swallow its cancellation on Python 3.11
benedikt-bartscher
marked this pull request as ready for review
October 11, 2026 11:12
Contributor
There was a problem hiding this comment.
All reported issues were addressed across 4 files
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
…ts lock until the write lands
…stead of a try in the loop
This branch has not been 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.
Under CPU load, our app's events stalled for 5 or 10 seconds (the oplock hold time and the lock expiration), and some updates made under a lease were lost.
StateManagerRedishad several ways to lose a lock or a wakeup:supersedesand a newon_load_internalcancel events at any await. This covers aSET NXwhose reply never arrived, the awaits in_try_modify_statebefore a lease or the single update owns the lock, and a lease task cancelled before its first step, which never enters the context that releases the lock.GETDEL, so a holder releasing after its lock expired deleted the next holder's lock.LockExpiredErrorand dropped every change made under the lease.This PR:
AsyncExitStack.pop_all()once the state is fetchedLockExpiredErrorEach case has a test in
tests/units/istate/manager/test_redis.pythat fails without the fix.test_oplock_immediate_cancelnow checks the outcome, because its lease can be cancelled before it starts.With a script that cancels a waiter around the handoff (2 s lock expiration, 50 ms redis latency), 19 of 30 waiters waited out the expiration before and none of 60 after. A fuzzer with up to 2 s holders lost up to 23 of 26 increments per round before and none after.
The unit tests pass (12512 without Redis, 12525 against Redis with and without oplock).