Repository navigation
fix(deps): require anyio>=4.15 so CapacityLimiter holds its bound - #224
Merged
Merged
Conversation
anyio before 4.15 woke the next waiter on release without handing it the
token. A task scheduled ahead of that waiter found the wait queue empty,
took the free token, and the waiter took one too: the limiter held one task
over its bound. Every stage and model concurrency limit is a
CapacityLimiter, so `concurrency_limits={"infer": 4}` occasionally ran 5
inferences at once -- the intermittent `5 <= 4` in
TestE2EStageConcurrency::test_stage_concurrency_limit_allows_higher.
4.15 adds the waiter to the borrowers before waking it. The floor pulls
typing-extensions to 4.16 (anyio 4.15's own requirement), declared so the
lock bump is reviewable. A deterministic regression test pins the handoff.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Type
Summary
anyio.CapacityLimiter. Before anyio 4.15, a release woke the next waiter without handing it the token. A task scheduled ahead of that waiter found the wait queue empty and a free slot, so it took the token; then the waiter took one too.assert 5 <= 4intest_runner.py::TestE2EStageConcurrency::test_stage_concurrency_limit_allows_higher. sieval and the test are both correct.concurrency_limit,concurrency_limitsand a model'sconcurrency_limitcan occasionally admit one extra in-flight request. That is harmless for most endpoints, but can draw a 429 from one rate-limited to an exact concurrency.anyio>=4.15.0. 4.15 adds the waiter to the borrowers before waking it (_notify_next_waiter). Bisected with a deterministic repro: 4.12.0, 4.12.1, 4.13.0 and 4.14.0 all run 2 tasks under a limit of 1; 4.15.0 and 4.15.1 run 1.typing-extensions>=4.16.0, so the lock moves it 4.15.0 → 4.16.0. It is declared inpyproject.tomlso the bump is reviewable rather than resolved into existence (check_deps).TestCapacityLimiterHandoffintests/unit/core/utils/test_concurrency.pypins the handoff deterministically: no timing, one scheduling step.Related Issues
Found while trimming the unit suite in #222.
Test Plan
Automated
ruff check && ruff format --check, pre-commit incl. taplo +lock-drift)ty checkon the changed test)pytest tests/unit tests/integration tests/acceptance -m "not stress and not benchmark" -n 16with anyio 4.15.1 + typing-extensions 4.16.0 → 9644 passed, 2 skipped, no new warningsscripts/check_preflight.py --check check_deps→ PASS (2 justified moves)Manual
Regression test fails on anyio 4.12.0 (
assert 2 == 1) and passes on 4.15.1.The runner scenario (
concurrency_limits={"infer": 4}, 6 samples), 16 parallel processes × 150 runs:Checklist
Required (all PRs)
type(scope): description)AI-Generated Code - <model> (<provider>)in module docstringcore/If: New Dependency
typing-extensionsis default, as anyio's own requirement, not a new import🤖 Generated with Claude Code