Skip to content

Commit 393035a

Browse files
Use asyncio for synchronization
1 parent e987df2 commit 393035a

10 files changed

+216
-141
lines changed

httpcore/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ def __init__(self, *args, **kwargs): # type: ignore
130130
"WriteError",
131131
]
132132

133-
__version__ = "1.0.5"
133+
__version__ = "1.0.6"
134134

135135

136136
__locals = locals()

httpcore/_async/connection_pool.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -299,11 +299,16 @@ def _assign_requests_to_connections(self) -> List[AsyncConnectionInterface]:
299299
return closing_connections
300300

301301
async def _close_connections(self, closing: List[AsyncConnectionInterface]) -> None:
302+
if not closing:
303+
return
304+
302305
# Close connections which have been removed from the pool.
303-
with AsyncShieldCancellation():
306+
async def close() -> None:
304307
for connection in closing:
305308
await connection.aclose()
306309

310+
await AsyncShieldCancellation.shield(close)
311+
307312
async def aclose(self) -> None:
308313
# Explicitly close the connection pool.
309314
# Clears all existing requests and connections.
@@ -369,9 +374,9 @@ async def __aiter__(self) -> AsyncIterator[bytes]:
369374
async def aclose(self) -> None:
370375
if not self._closed:
371376
self._closed = True
372-
with AsyncShieldCancellation():
373-
if hasattr(self._stream, "aclose"):
374-
await self._stream.aclose()
377+
378+
if hasattr(self._stream, "aclose"):
379+
await AsyncShieldCancellation.shield(self._stream.aclose)
375380

376381
with self._pool._optional_thread_lock:
377382
self._pool._requests.remove(self._pool_request)

httpcore/_async/http11.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,8 @@ async def handle_async_request(self, request: Request) -> Response:
137137
},
138138
)
139139
except BaseException as exc:
140-
with AsyncShieldCancellation():
141-
async with Trace("response_closed", logger, request) as trace:
142-
await self._response_closed()
140+
async with Trace("response_closed", logger, request) as trace:
141+
await AsyncShieldCancellation.shield(self._response_closed)
143142
raise exc
144143

145144
# Sending the request...
@@ -344,8 +343,7 @@ async def __aiter__(self) -> AsyncIterator[bytes]:
344343
# If we get an exception while streaming the response,
345344
# we want to close the response (and possibly the connection)
346345
# before raising that exception.
347-
with AsyncShieldCancellation():
348-
await self.aclose()
346+
await AsyncShieldCancellation.shield(self.aclose)
349347
raise exc
350348

351349
async def aclose(self) -> None:

httpcore/_async/http2.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,7 @@ async def handle_async_request(self, request: Request) -> Response:
108108
async with Trace("send_connection_init", logger, request, kwargs):
109109
await self._send_connection_init(**kwargs)
110110
except BaseException as exc:
111-
with AsyncShieldCancellation():
112-
await self.aclose()
111+
await AsyncShieldCancellation.shield(self.aclose)
113112
raise exc
114113

115114
self._sent_connection_init = True
@@ -160,12 +159,15 @@ async def handle_async_request(self, request: Request) -> Response:
160159
"stream_id": stream_id,
161160
},
162161
)
163-
except BaseException as exc: # noqa: PIE786
164-
with AsyncShieldCancellation():
162+
except BaseException as exc:
163+
164+
async def close() -> None:
165165
kwargs = {"stream_id": stream_id}
166166
async with Trace("response_closed", logger, request, kwargs):
167167
await self._response_closed(stream_id=stream_id)
168168

169+
await AsyncShieldCancellation.shield(close)
170+
169171
if isinstance(exc, h2.exceptions.ProtocolError):
170172
# One case where h2 can raise a protocol error is when a
171173
# closed frame has been seen by the state machine.
@@ -577,8 +579,7 @@ async def __aiter__(self) -> typing.AsyncIterator[bytes]:
577579
# If we get an exception while streaming the response,
578580
# we want to close the response (and possibly the connection)
579581
# before raising that exception.
580-
with AsyncShieldCancellation():
581-
await self.aclose()
582+
await AsyncShieldCancellation.shield(self.aclose)
582583
raise exc
583584

584585
async def aclose(self) -> None:

httpcore/_sync/connection_pool.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -299,11 +299,16 @@ def _assign_requests_to_connections(self) -> List[ConnectionInterface]:
299299
return closing_connections
300300

301301
def _close_connections(self, closing: List[ConnectionInterface]) -> None:
302+
if not closing:
303+
return
304+
302305
# Close connections which have been removed from the pool.
303-
with ShieldCancellation():
306+
def close() -> None:
304307
for connection in closing:
305308
connection.close()
306309

310+
ShieldCancellation.shield(close)
311+
307312
def close(self) -> None:
308313
# Explicitly close the connection pool.
309314
# Clears all existing requests and connections.
@@ -369,9 +374,9 @@ def __iter__(self) -> Iterator[bytes]:
369374
def close(self) -> None:
370375
if not self._closed:
371376
self._closed = True
372-
with ShieldCancellation():
373-
if hasattr(self._stream, "close"):
374-
self._stream.close()
377+
378+
if hasattr(self._stream, "close"):
379+
ShieldCancellation.shield(self._stream.close)
375380

376381
with self._pool._optional_thread_lock:
377382
self._pool._requests.remove(self._pool_request)

httpcore/_sync/http11.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,8 @@ def handle_request(self, request: Request) -> Response:
137137
},
138138
)
139139
except BaseException as exc:
140-
with ShieldCancellation():
141-
with Trace("response_closed", logger, request) as trace:
142-
self._response_closed()
140+
with Trace("response_closed", logger, request) as trace:
141+
ShieldCancellation.shield(self._response_closed)
143142
raise exc
144143

145144
# Sending the request...
@@ -344,8 +343,7 @@ def __iter__(self) -> Iterator[bytes]:
344343
# If we get an exception while streaming the response,
345344
# we want to close the response (and possibly the connection)
346345
# before raising that exception.
347-
with ShieldCancellation():
348-
self.close()
346+
ShieldCancellation.shield(self.close)
349347
raise exc
350348

351349
def close(self) -> None:

httpcore/_sync/http2.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,7 @@ def handle_request(self, request: Request) -> Response:
108108
with Trace("send_connection_init", logger, request, kwargs):
109109
self._send_connection_init(**kwargs)
110110
except BaseException as exc:
111-
with ShieldCancellation():
112-
self.close()
111+
ShieldCancellation.shield(self.close)
113112
raise exc
114113

115114
self._sent_connection_init = True
@@ -160,12 +159,15 @@ def handle_request(self, request: Request) -> Response:
160159
"stream_id": stream_id,
161160
},
162161
)
163-
except BaseException as exc: # noqa: PIE786
164-
with ShieldCancellation():
162+
except BaseException as exc:
163+
164+
def close() -> None:
165165
kwargs = {"stream_id": stream_id}
166166
with Trace("response_closed", logger, request, kwargs):
167167
self._response_closed(stream_id=stream_id)
168168

169+
ShieldCancellation.shield(close)
170+
169171
if isinstance(exc, h2.exceptions.ProtocolError):
170172
# One case where h2 can raise a protocol error is when a
171173
# closed frame has been seen by the state machine.
@@ -577,8 +579,7 @@ def __iter__(self) -> typing.Iterator[bytes]:
577579
# If we get an exception while streaming the response,
578580
# we want to close the response (and possibly the connection)
579581
# before raising that exception.
580-
with ShieldCancellation():
581-
self.close()
582+
ShieldCancellation.shield(self.close)
582583
raise exc
583584

584585
def close(self) -> None:

0 commit comments

Comments
 (0)