azure-sdk-for-python
azure-sdk-for-python copied to clipboard
Async clients close() does not close TCP connection
It appears that async clients close() method does not close the underlying TCP connection. While running the app below, when the app is waiting for input the second time, session.closed is True, but the TCP connection is still ESTABLISHED (verified by running netstat -an).
import asyncio
import os
from azure.storage.blob.aio import BlobClient
async def main():
client = BlobClient.from_connection_string(os.environ['STORAGE_CONNECTION_STRING'], 'container_name', 'blob_name')
session = None
async with client:
stream = await client.download_blob()
session = client._client._client._pipeline._transport.session
print(session)
print('session.closed: ' + str(session.closed))
input('Press Enter to continue...')
print('session.closed: ' + str(session.closed))
input('Press Enter to continue...')
asyncio.run(main())
It also repros with KeyVault SecretClient:
import asyncio
import os
from azure.keyvault.secrets.aio import SecretClient
from azure.identity.aio import DefaultAzureCredential
async def main():
vault_url = os.environ["VAULT_URL"]
credential = DefaultAzureCredential(additionally_allowed_tenants=['*'])
session = None
async with SecretClient(vault_url=vault_url, credential=credential) as client:
await client.get_secret("secret_name")
session = client._client._client._pipeline._transport.session
print(session)
print('session.closed: ' + str(session.closed))
input('Press Enter to continue...')
print('session.closed: ' + str(session.closed))
input('Press Enter to continue...')
asyncio.run(main())
However, this does not repro when using aiohttp.ClientSession directly. When this app is waiting for input the second time, session.closed is True, and the TCP connection is in TIME_WAIT (meaning the app has closed the connection).
import aiohttp
import asyncio
async def main():
session = aiohttp.ClientSession()
async with session:
async with session.get('http://example.org') as resp:
print(resp.status)
print('session.closed: ' + str(session.closed))
input('Press Enter to continue...')
print('session.closed: ' + str(session.closed))
input('Press Enter to continue...')
asyncio.run(main())
Does not repro when using sync BlobClient:
import os
from azure.storage.blob import BlobClient
client = BlobClient.from_connection_string(os.environ['STORAGE_CONNECTION_STRING'], 'container_name', 'blob_name')
stream = client.download_blob()
input('Press Enter to continue...')
client.close()
input('Press Enter to continue...')
Or when using AsyncPipeline directly:
import asyncio
from azure.core.pipeline.transport import HttpRequest
from azure.core.pipeline import AsyncPipeline
from azure.core.pipeline.transport import AioHttpTransport
async def main():
request = HttpRequest("GET", 'https://example.org')
async with AsyncPipeline(AioHttpTransport()) as pipeline:
response = await pipeline.run(request)
input('Press Enter to continue...')
input('Press Enter to continue...')
asyncio.run(main())
Label prediction was below confidence level 0.6 for Model:ServiceLabels: 'Service Bus:0.53615165,Storage:0.27983,Azure.Core:0.03194222'
Are there any update or workarounds on this ?
Not sure but my issue #32458 may be related to this, any solution or work around? it is a pretty bad issue as it doesn't allow to get multiple blobs at once essentially making the whole aio blob storage client useless.