Remove asyncio.shield in _drain_helper to fix unhandled future warnings#12293
Open
joaquinhuigomez wants to merge 3 commits intoaio-libs:masterfrom
Open
Remove asyncio.shield in _drain_helper to fix unhandled future warnings#12293joaquinhuigomez wants to merge 3 commits intoaio-libs:masterfrom
joaquinhuigomez wants to merge 3 commits intoaio-libs:masterfrom
Conversation
…rnings Replace asyncio.shield(waiter) with direct await on waiter in _drain_helper. HTTP/1.1 has a single consumer per drain waiter, so shield is unnecessary and causes "Future exception was never retrieved" warnings on cancellation. Closes aio-libs#12281
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #12293 +/- ##
==========================================
- Coverage 99.11% 99.10% -0.01%
==========================================
Files 130 130
Lines 45446 45468 +22
Branches 2398 2398
==========================================
+ Hits 45044 45063 +19
- Misses 272 275 +3
Partials 130 130
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
mypy flags the final assertion as unreachable after the suppress(CancelledError) context manager. The code IS reachable at runtime — the suppress catches the CancelledError from the cancelled task, and execution continues normally.
| assert pr._drain_waiter is None | ||
|
|
||
|
|
||
| async def test_cancelled_drain_no_unhandled_future_warning() -> None: |
Member
There was a problem hiding this comment.
Sorry, but I don't feel this test is validating aiohttp's behaviour. It may or may not match aiohttp's implementation at a given point in time.
As mentioned in the issue, I'd like to see a full functional test which shouldn't be too difficult given the reporter's reproducer and the example test I linked to.
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.
Replace
asyncio.shield(waiter)with directawait waiterin_drain_helper.HTTP/1.1 has a single consumer per drain waiter, so the shield is unnecessary. When a handler task is cancelled during write backpressure,
asyncio.shieldkeeps the original waiter alive and uncancelled.connection_lostthen callsset_exceptionon it, but nobody is awaiting it anymore, producing noisy "Future exception was never retrieved" warnings.Without the shield, cancellation propagates directly to the waiter.
connection_lostfindswaiter.done() == Trueand skipsset_exception.Includes a regression test that verifies the waiter is properly cancelled (not left with an unhandled exception) when the task is cancelled during backpressure and
connection_lostfires afterward.Closes #12281