Skip to content

Commit 333c20c

Browse files
Inner task finished by best effort
1 parent 2402e8e commit 333c20c

File tree

3 files changed

+22
-18
lines changed

3 files changed

+22
-18
lines changed

httpcore/_async/http2.py

+5-7
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,11 @@ async def handle_async_request(self, request: Request) -> Response:
160160
},
161161
)
162162
except BaseException as exc:
163-
164-
async def close() -> None:
165-
kwargs = {"stream_id": stream_id}
166-
async with Trace("response_closed", logger, request, kwargs):
167-
await self._response_closed(stream_id=stream_id)
168-
169-
await async_cancel_shield(close)
163+
kwargs = {"stream_id": stream_id}
164+
async with Trace("response_closed", logger, request, kwargs):
165+
await async_cancel_shield(
166+
lambda: self._response_closed(stream_id=stream_id)
167+
)
170168

171169
if isinstance(exc, h2.exceptions.ProtocolError):
172170
# One case where h2 can raise a protocol error is when a

httpcore/_sync/http2.py

+5-7
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,11 @@ def handle_request(self, request: Request) -> Response:
160160
},
161161
)
162162
except BaseException as exc:
163-
164-
def close() -> None:
165-
kwargs = {"stream_id": stream_id}
166-
with Trace("response_closed", logger, request, kwargs):
167-
self._response_closed(stream_id=stream_id)
168-
169-
sync_cancel_shield(close)
163+
kwargs = {"stream_id": stream_id}
164+
with Trace("response_closed", logger, request, kwargs):
165+
sync_cancel_shield(
166+
lambda: self._response_closed(stream_id=stream_id)
167+
)
170168

171169
if isinstance(exc, h2.exceptions.ProtocolError):
172170
# One case where h2 can raise a protocol error is when a

httpcore/_synchronization.py

+12-4
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,18 @@ async def async_cancel_shield(
205205
await shielded()
206206
else:
207207
inner_task = asyncio.create_task(shielded())
208-
try:
209-
await asyncio.shield(inner_task)
210-
except asyncio.CancelledError:
211-
return
208+
retry = False
209+
while True:
210+
try:
211+
await asyncio.shield(inner_task)
212+
break
213+
except asyncio.CancelledError:
214+
if inner_task.done() or retry:
215+
break
216+
# We may get multiple cancellations.
217+
# Retry once to get inner_task finished here by best effort.
218+
retry = True
219+
continue
212220

213221

214222
# Our thread-based synchronization primitives...

0 commit comments

Comments
 (0)