Repository navigation
fix: let heavy work wait without losing attempts - #211
Merged
Merged
Conversation
…wing through a stop
yesbert
force-pushed
the
fix/let-heavy-work-wait-without-losing-attempts
branch
from
October 23, 2026 13:35
fbec483 to
5bdd0ce
Compare
Owner
Author
|
Copilot could not review this PR because the quota is exhausted, so a local review at
The finding's chain is still reproduced by |
This was referenced Oct 23, 2026
Merged
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.
What this changes
On the Orleans execution model, a recorded command no longer uses up its attempts by waiting. A burst of heavy commands many times the cluster-wide limit becomes a backlog that is worked off. Only a handler that runs and fails counts against
MessageRetry:MaxDeliveryAttempts.IntentRenewals, one loop per silo registered byAddStrataraAggregateGrains, renews every command the silo holds every third of the grace, in batches of 1,000. The holders are aggregate orders, runners and heavy pools, and the renewal goes through the newICommandIntentStore.RenewManyAsync. Its default renews one at a time, and the EF store overrides it with oneUPDATEper batch. Leases register and release their commands instead of running a timer each. A lease built without the loop, as in the unit tests, keeps its own timer. A failed batch is logged once (117_134).HeavyWorkOptions.QueuedLimitPerPool(default 256) bounds the commands one pool holds, running and waiting. A hand-over beyond it is refused, its attempt is given back, and it is logged at debug (117_133). The command waits in the store and is handed over again after the grace.ReturnAttemptAsync.The first commit archives
let-a-consumer-choose-the-pool-size(#209).Implements the OpenSpec change
let-heavy-work-wait-without-losing-attempts(approved). It adds Waiting costs a recorded command no attempt toorleans-execution.Why
A consumer measured 10,000 documents with four heavy commands each and
ClusterWideLimit = 4. Per-lease renewals exhausted the connection pool, the records of waiting commands lapsed, the drain handed them over again, and each hand-over counted an attempt. After 32 minutes 16 commands were kept, 13 of them with no failure recorded.How it was verified
IntentRenewalsTests(new, unit):HeavyBacklogTests(new, PostgreSQL):RenewManyAsyncrenews exactly the listed, not-kept records.Full
Stratara.Orleans.IntegrationTests: 213/213../scripts/local-gauntlet.shpasses