Skip to content

Commit 266608d

Browse files
[PR #8611/1fcef940 backport][3.10] Fix handler waiting on shutdown (#8627)
Co-authored-by: Sam Bull <[email protected]>
1 parent a55d3e0 commit 266608d

File tree

2 files changed

+9
-3
lines changed

2 files changed

+9
-3
lines changed

CHANGES/8611.bugfix.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed an edge case where shutdown would wait for timeout when handler was already completed -- by :user:`Dreamsorcerer`.

aiohttp/web_protocol.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ class RequestHandler(BaseProtocol):
148148
"_lingering_time",
149149
"_messages",
150150
"_message_tail",
151+
"_handler_waiter",
151152
"_waiter",
152153
"_task_handler",
153154
"_upgrade",
@@ -204,6 +205,7 @@ def __init__(
204205
self._message_tail = b""
205206

206207
self._waiter: Optional[asyncio.Future[None]] = None
208+
self._handler_waiter: Optional[asyncio.Future[None]] = None
207209
self._task_handler: Optional[asyncio.Task[None]] = None
208210

209211
self._upgrade = False
@@ -262,11 +264,11 @@ async def shutdown(self, timeout: Optional[float] = 15.0) -> None:
262264
if self._waiter:
263265
self._waiter.cancel()
264266

265-
# Wait for graceful disconnection
266-
if self._current_request is not None:
267+
# Wait for graceful handler completion
268+
if self._handler_waiter is not None:
267269
with suppress(asyncio.CancelledError, asyncio.TimeoutError):
268270
async with ceil_timeout(timeout):
269-
await self._current_request.wait_for_disconnection()
271+
await self._handler_waiter
270272
# Then cancel handler and wait
271273
with suppress(asyncio.CancelledError, asyncio.TimeoutError):
272274
async with ceil_timeout(timeout):
@@ -450,6 +452,7 @@ async def _handle_request(
450452
start_time: float,
451453
request_handler: Callable[[BaseRequest], Awaitable[StreamResponse]],
452454
) -> Tuple[StreamResponse, bool]:
455+
self._handler_waiter = self._loop.create_future()
453456
try:
454457
try:
455458
self._current_request = request
@@ -479,6 +482,8 @@ async def _handle_request(
479482
)
480483

481484
reset = await self.finish_response(request, resp, start_time)
485+
finally:
486+
self._handler_waiter.set_result(None)
482487

483488
return resp, reset
484489

0 commit comments

Comments
 (0)