Repository navigation
fix: hold an actor's turn until a cancelled call finishes - #1877
Merged
siri-varma merged 1 commit intoOct 27, 2026
Merged
siri-varma merged 1 commit into
siri-varma merged 1 commit into
Conversation
When a caller cancels an actor call while it runs, daprd releases the actor and sends the next call, but the SDK kept running the cancelled method, so two turns ran at once on the same actor. ActorManager now runs activation, method calls and deactivation through a per-actor turn lock. A turn keeps the actor until its code and the state save finish, even if its request is cancelled. Turns that are still waiting are dropped when cancelled. Fixes dapr#1871 Signed-off-by: Javier Aliaga <javier@diagrid.io>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1877 +/- ##
============================================
+ Coverage 80.52% 80.63% +0.10%
- Complexity 2835 2850 +15
============================================
Files 274 275 +1
Lines 8412 8459 +47
Branches 905 911 +6
============================================
+ Hits 6774 6821 +47
Misses 1272 1272
Partials 366 366 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
siri-varma
approved these changes
Oct 27, 2026
javier-aliaga
added a commit
that referenced
this pull request
Oct 27, 2026
) When a caller cancels an actor call while it runs, daprd releases the actor and sends the next call, but the SDK kept running the cancelled method, so two turns ran at once on the same actor. ActorManager now runs activation, method calls and deactivation through a per-actor turn lock. A turn keeps the actor until its code and the state save finish, even if its request is cancelled. Turns that are still waiting are dropped when cancelled. Fixes #1871 (cherry picked from commit 47b9bb5) Signed-off-by: Javier Aliaga <javier@diagrid.io> Co-authored-by: Javier Aliaga <javier@diagrid.io>
javier-aliaga
deleted the
fix/actors-a-call-cancelled-while-it-runs-frees-the
branch
October 28, 2026 10:22
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.
Description
When a caller cancels an actor call while the method runs, daprd releases the actor and sends the next call for the same actor ID. The SDK kept running the cancelled method, so two calls ran on the same actor at once. Over HTTP the cancelled call also skipped
onPostActorMethod, so its state changes were not saved.ActorManagernow runs activation, method calls (timers and reminders included) and deactivation through a new per-actorActorTurnLock. Calls for one actor run one at a time, in arrival order. Calls for different actors still run in parallel.onPostActorMethodfinish. Its caller stops waiting right away.Schedulers.boundedElastic(), so a long queue does not grow the stack.Behavior changes:
Tests:
ActorTurnLockTestcovers ordering, cancellation, errors, empty results, a 10,000-call queue and context propagation.ActorManagerTestadds three cases. A cancelled call still runsonPostActorMethodbefore the next call starts. Ten concurrent activations create one actor. Deactivation waits for the running call.ActorCancelledCallIT(HTTP app) andActorCancelledCallGrpcHostIT(actor event stream) run against daprd. Each cancels five 2-second calls after 500 ms and checks that only one ran at a time. Both fail on master with 4 calls running at once, and pass with this change.Issue reference
Fixes #1871
Checklist