asyncio.exceptions.CancelledError not releasing connection from the connection pool
niraj8989 opened this issue · 3 comments
We have an application that is downloading file from third party server.
While downloading if anything happens with the process we are getting CancelledError but it is not releasing the connection from the connection pool.
File "test/filesystem/cxfiles.py", line 304, in _download_file_once
async for chunk in self.cxfiles_client.download_service_request_attachment(
File "test/filesystem/cxfiles_client.py", line 391, in download_service_request_attachment
yield chunk
File "/usr/lib/python3.8/contextlib.py", line 189, in aexit
await self.gen.athrow(typ, value, traceback)
File "/home/niraj/candela/candela_nx/src/test/filesystem/cxfiles_client.py", line 285, in stream_post
yield response
File "/usr/lib/python3.8/contextlib.py", line 189, in aexit
await self.gen.athrow(typ, value, traceback)
File "/home/niraj/venv/lib/python3.8/site-packages/httpx/_client.py", line 1579, in stream
await response.aclose()
File "/home/niraj/venv/lib/python3.8/site-packages/httpx/_models.py", line 993, in aclose
await self.stream.aclose()
File "/home/niraj/venv/lib/python3.8/site-packages/httpx/_client.py", line 152, in aclose
await self._stream.aclose()
File "/home/niraj/venv/lib/python3.8/site-packages/httpx/_transports/default.py", line 244, in aclose
await self._httpcore_stream.aclose() # type: ignore
File "/home/niraj/venv/lib/python3.8/site-packages/httpcore/_async/connection_pool.py", line 356, in aclose
await self._pool.response_closed(self._status)
File "/home/niraj/venv/lib/python3.8/site-packages/httpcore/_async/connection_pool.py", line 277, in response_closed
async with self._pool_lock:
File "/home/niraj/venv/lib/python3.8/site-packages/httpcore/_synchronization.py", line 15, in aenter
await self._lock.acquire()
File "/home/niraj/venv/lib/python3.8/site-packages/anyio/_core/_synchronization.py", line 121, in acquire
await checkpoint_if_cancelled()
File "/home/niraj/venv/lib/python3.8/site-packages/anyio/lowlevel.py", line 42, in checkpoint_if_cancelled
await get_asynclib().checkpoint_if_cancelled()
File "/home/niraj/venv/lib/python3.8/site-packages/anyio/_backends/_asyncio.py", line 530, in checkpoint_if_cancelled
await sleep(0)
File "/usr/lib/python3.8/asyncio/tasks.py", line 644, in sleep
await __sleep0()
File "/usr/lib/python3.8/asyncio/tasks.py", line 638, in __sleep0
yield
asyncio.exceptions.CancelledError
Faced the same issue. In case you cancel request in the middle there is possible situation that pool doesn't release connection. As I can see you can reproduce this with the test case below
@pytest.mark.anyio
async def test_cancel_request():
network_backend = AsyncMockBackend(
[
b"HTTP/1.1 200 OK\r\n",
b"Content-Type: plain/text\r\n",
b"Content-Length: 13\r\n",
b"\r\n",
b"Hello, world!",
]
)
async def get(_pool):
print('1')
async with pool.stream("GET", "https://example.com") as _:
print('2')
await anyio.sleep(1)
print('3')
print('4')
async with AsyncConnectionPool(
network_backend=network_backend,
max_connections=1,
) as pool:
with anyio.move_on_after(1) as scope:
async with anyio.create_task_group() as tg:
tg.start_soon(get, pool)
print(scope.cancel_called)
print(pool.connections)
async with pool.stream("GET", "https://example2.com") as response:
await response.aread()
print(pool.connections)
assert False
This issue appears to be the concrete scenario of #642.
Should we leave this ticked open?
Closing as a duplicate of #642