Skip to content

Fix ConcurrencyLimitTest flakiness on threeNodes (#435)#436

Merged
tillrohrmann merged 1 commit into
restatedev:mainfrom
tillrohrmann:issues/435
Jun 17, 2026
Merged

Fix ConcurrencyLimitTest flakiness on threeNodes (#435)#436
tillrohrmann merged 1 commit into
restatedev:mainfrom
tillrohrmann:issues/435

Conversation

@tillrohrmann

Copy link
Copy Markdown
Contributor

The test counted the downstream Blocker/%/run invocations as a proxy for how many scoped invocations are running. That count is cumulative, not concurrent: each BlockingProxy calls a distinct Blocker key, and once a Blocker/run is spawned it blocks on an awakeable and stays running until resolved. Under a leadership change a running BlockingProxy yields its slot to a held one, but the Blocker/run it already spawned keeps running, so the Blocker count can exceed limit even though the limit is respected. The runtime only guarantees no more than limit scoped invocations run concurrently, not that it is always the same set.

Count the scoped BlockingProxy invocations with status running instead, which settles to exactly limit and tolerates leadership-change churn.

Additionally track, via in-process atomics on BlockingProxy.block, the maximum number of handlers that ever ran concurrently, and assert it never exceeds limit. This strict bound is only asserted on single-node clusters: on multi-node clusters a leadership change can momentarily run more than limit handlers because the old leader's in-flight invocations are not guaranteed to be torn down before the new leader dispatches replacements.

Also rename the test to drop "action" from "action concurrency limit".

This fixes #435

The test counted the downstream `Blocker/%/run` invocations as a proxy for
how many scoped invocations are running. That count is cumulative, not
concurrent: each BlockingProxy calls a distinct Blocker key, and once a
Blocker/run is spawned it blocks on an awakeable and stays running until
resolved. Under a leadership change a running BlockingProxy yields its slot
to a held one, but the Blocker/run it already spawned keeps running, so the
Blocker count can exceed `limit` even though the limit is respected. The
runtime only guarantees no more than `limit` scoped invocations run
concurrently, not that it is always the same set.

Count the scoped BlockingProxy invocations with status `running` instead,
which settles to exactly `limit` and tolerates leadership-change churn.

Additionally track, via in-process atomics on BlockingProxy.block, the
maximum number of handlers that ever ran concurrently, and assert it never
exceeds `limit`. This strict bound is only asserted on single-node clusters:
on multi-node clusters a leadership change can momentarily run more than
`limit` handlers because the old leader's in-flight invocations are not
guaranteed to be torn down before the new leader dispatches replacements.

Also rename the test to drop "action" from "action concurrency limit".

This fixes restatedev#435.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Address review: make ConcurrencyLimitTest @isolated and single-node only

The strict in-process concurrency bound is the point of the test and can
only be asserted on single-node clusters, so remove the test from the
threeNodes suite. Mark the class @isolated so it stays isolated if more
tests are added to it later.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tillrohrmann tillrohrmann merged commit e7d3309 into restatedev:main Jun 17, 2026
3 checks passed
@tillrohrmann tillrohrmann deleted the issues/435 branch June 17, 2026 14:53
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 17, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

threeNodes => ConcurrencyLimitTest => Action concurrency limit on a scope holds excess invocations and releases on completion fails

2 participants