Skip to content

Commit 1d761e1

Browse files
authored
[PR #9756/44d809f backport][3.11] Avoid tracking connections per host when there is no limit per host (#9758)
1 parent df9c657 commit 1d761e1

File tree

3 files changed

+19
-15
lines changed

3 files changed

+19
-15
lines changed

CHANGES/9756.misc.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improved performance of :py:class:`aiohttp.BaseConnector` when there is no ``limit_per_host`` -- by :user:`bdraco`.

aiohttp/connector.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,8 @@ async def connect(
531531

532532
placeholder = cast(ResponseHandler, _TransportPlaceholder())
533533
self._acquired.add(placeholder)
534-
self._acquired_per_host[key].add(placeholder)
534+
if self._limit_per_host:
535+
self._acquired_per_host[key].add(placeholder)
535536

536537
try:
537538
# Traces are done inside the try block to ensure that the
@@ -557,11 +558,12 @@ async def connect(
557558
# be no awaits after the proto is added to the acquired set
558559
# to ensure that the connection is not left in the acquired set
559560
# on cancellation.
560-
acquired_per_host = self._acquired_per_host[key]
561561
self._acquired.remove(placeholder)
562-
acquired_per_host.remove(placeholder)
563562
self._acquired.add(proto)
564-
acquired_per_host.add(proto)
563+
if self._limit_per_host:
564+
acquired_per_host = self._acquired_per_host[key]
565+
acquired_per_host.remove(placeholder)
566+
acquired_per_host.add(proto)
565567
return Connection(self, key, proto, self._loop)
566568

567569
async def _wait_for_available_connection(
@@ -626,7 +628,8 @@ async def _get(
626628
# The very last connection was reclaimed: drop the key
627629
del self._conns[key]
628630
self._acquired.add(proto)
629-
self._acquired_per_host[key].add(proto)
631+
if self._limit_per_host:
632+
self._acquired_per_host[key].add(proto)
630633
if traces:
631634
for trace in traces:
632635
try:
@@ -680,7 +683,7 @@ def _release_acquired(self, key: "ConnectionKey", proto: ResponseHandler) -> Non
680683
return
681684

682685
self._acquired.discard(proto)
683-
if conns := self._acquired_per_host.get(key):
686+
if self._limit_per_host and (conns := self._acquired_per_host.get(key)):
684687
conns.discard(proto)
685688
if not conns:
686689
del self._acquired_per_host[key]

tests/test_connector.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ async def test_get_expired_ssl(loop: asyncio.AbstractEventLoop) -> None:
375375

376376
async def test_release_acquired(loop, key) -> None:
377377
proto = mock.Mock()
378-
conn = aiohttp.BaseConnector(loop=loop, limit=5)
378+
conn = aiohttp.BaseConnector(loop=loop, limit=5, limit_per_host=10)
379379
conn._release_waiter = mock.Mock()
380380

381381
conn._acquired.add(proto)
@@ -562,7 +562,7 @@ async def test_release_close(loop, key) -> None:
562562
async def test__release_acquired_per_host1(
563563
loop: asyncio.AbstractEventLoop, key: ConnectionKey
564564
) -> None:
565-
conn = aiohttp.BaseConnector()
565+
conn = aiohttp.BaseConnector(limit_per_host=10)
566566
conn._release_acquired(key, create_mocked_conn(loop))
567567
assert len(conn._acquired_per_host) == 0
568568

@@ -572,7 +572,7 @@ async def test__release_acquired_per_host1(
572572
async def test__release_acquired_per_host2(
573573
loop: asyncio.AbstractEventLoop, key: ConnectionKey
574574
) -> None:
575-
conn = aiohttp.BaseConnector()
575+
conn = aiohttp.BaseConnector(limit_per_host=10)
576576
handler = create_mocked_conn(loop)
577577
conn._acquired_per_host[key].add(handler)
578578
conn._release_acquired(key, handler)
@@ -584,7 +584,7 @@ async def test__release_acquired_per_host2(
584584
async def test__release_acquired_per_host3(
585585
loop: asyncio.AbstractEventLoop, key: ConnectionKey
586586
) -> None:
587-
conn = aiohttp.BaseConnector()
587+
conn = aiohttp.BaseConnector(limit_per_host=10)
588588
handler = create_mocked_conn(loop)
589589
handler2 = create_mocked_conn(loop)
590590
conn._acquired_per_host[key].add(handler)
@@ -2466,7 +2466,7 @@ async def test_connect_with_limit(
24662466
"GET", URL("http://localhost:80"), loop=loop, response_class=mock.Mock()
24672467
)
24682468

2469-
conn = aiohttp.BaseConnector(loop=loop, limit=1)
2469+
conn = aiohttp.BaseConnector(loop=loop, limit=1, limit_per_host=10)
24702470
conn._conns[key] = deque([(proto, loop.time())])
24712471
conn._create_connection = mock.Mock()
24722472
conn._create_connection.return_value = loop.create_future()
@@ -2663,7 +2663,7 @@ async def f():
26632663
connection2 = await conn.connect(req, None, ClientTimeout())
26642664
acquired = True
26652665
assert 1 == len(conn._acquired)
2666-
assert 1 == len(conn._acquired_per_host[key])
2666+
assert not conn._acquired_per_host
26672667
connection2.release()
26682668

26692669
task = loop.create_task(f())
@@ -2810,7 +2810,7 @@ async def test_connect_waiters_cleanup_key_error(loop) -> None:
28102810

28112811
req = ClientRequest("GET", URL("http://host:80"), loop=loop)
28122812

2813-
conn = aiohttp.BaseConnector(loop=loop, limit=1)
2813+
conn = aiohttp.BaseConnector(loop=loop, limit=1, limit_per_host=10)
28142814
conn._available_connections = mock.Mock(return_value=0)
28152815

28162816
t = loop.create_task(conn.connect(req, None, ClientTimeout()))
@@ -2901,7 +2901,7 @@ async def test_force_close_and_explicit_keep_alive(loop) -> None:
29012901

29022902

29032903
async def test_error_on_connection(loop, key) -> None:
2904-
conn = aiohttp.BaseConnector(limit=1, loop=loop)
2904+
conn = aiohttp.BaseConnector(limit=1, loop=loop, limit_per_host=10)
29052905

29062906
req = mock.Mock()
29072907
req.connection_key = key
@@ -2969,7 +2969,7 @@ async def create_connection(req, traces=None):
29692969

29702970

29712971
async def test_error_on_connection_with_cancelled_waiter(loop, key) -> None:
2972-
conn = aiohttp.BaseConnector(limit=1, loop=loop)
2972+
conn = aiohttp.BaseConnector(limit=1, loop=loop, limit_per_host=10)
29732973

29742974
req = mock.Mock()
29752975
req.connection_key = key

0 commit comments

Comments
 (0)