5
5
6
6
from .._backends .auto import AutoBackend
7
7
from .._backends .base import SOCKET_OPTION , AsyncNetworkBackend
8
- from .._exceptions import (
9
- ConnectionNotAvailable ,
10
- ServerDisconnectedError ,
11
- UnsupportedProtocol ,
12
- )
8
+ from .._exceptions import ConnectionNotAvailable , UnsupportedProtocol
13
9
from .._models import Origin , Request , Response
14
10
from .._synchronization import AsyncEvent , AsyncShieldCancellation , AsyncThreadLock
15
11
from .connection import AsyncHTTPConnection
@@ -200,7 +196,7 @@ async def handle_async_request(self, request: Request) -> Response:
200
196
response = await connection .handle_async_request (
201
197
pool_request .request
202
198
)
203
- except ( ConnectionNotAvailable , ServerDisconnectedError ) :
199
+ except ConnectionNotAvailable :
204
200
# In some cases a connection may initially be available to
205
201
# handle a request, but then become unavailable.
206
202
#
@@ -244,7 +240,7 @@ def _assign_requests_to_connections(self) -> List[AsyncConnectionInterface]:
244
240
closing_connections = []
245
241
246
242
# First we handle cleaning up any connections that are closed,
247
- # have expired their keep-alive , or surplus idle connections.
243
+ # have expired, or surplus idle connections.
248
244
for connection in list (self ._connections ):
249
245
if connection .is_closed ():
250
246
# log: "removing closed connection"
@@ -271,15 +267,12 @@ def _assign_requests_to_connections(self) -> List[AsyncConnectionInterface]:
271
267
for connection in self ._connections
272
268
if connection .can_handle_request (origin ) and connection .is_available ()
273
269
]
274
- idle_connections = [
275
- connection for connection in self ._connections if connection .is_idle ()
276
- ]
277
270
278
271
# There are three cases for how we may be able to handle the request:
279
272
#
280
273
# 1. There is an existing connection that can handle the request.
281
274
# 2. We can create a new connection to handle the request.
282
- # 3. We can close an idle connection and then create a new connection
275
+ # 3. We can close an idle/expired connection and then create a new connection
283
276
# to handle the request.
284
277
if available_connections :
285
278
# log: "reusing existing connection"
@@ -290,15 +283,19 @@ def _assign_requests_to_connections(self) -> List[AsyncConnectionInterface]:
290
283
connection = self .create_connection (origin )
291
284
self ._connections .append (connection )
292
285
pool_request .assign_to_connection (connection )
293
- elif idle_connections :
294
- # log: "closing idle connection"
295
- connection = idle_connections [0 ]
296
- self ._connections .remove (connection )
297
- closing_connections .append (connection )
298
- # log: "creating new connection"
299
- connection = self .create_connection (origin )
300
- self ._connections .append (connection )
301
- pool_request .assign_to_connection (connection )
286
+ else :
287
+ purged_connection = next (
288
+ (c for c in self ._connections if c .is_idle () or c .has_expired ()),
289
+ None ,
290
+ )
291
+ if purged_connection is not None :
292
+ # log: "closing idle connection"
293
+ self ._connections .remove (purged_connection )
294
+ closing_connections .append (purged_connection )
295
+ # log: "creating new connection"
296
+ connection = self .create_connection (origin )
297
+ self ._connections .append (connection )
298
+ pool_request .assign_to_connection (connection )
302
299
303
300
return closing_connections
304
301
0 commit comments