Skip to content

[Bug]: AzureAISearchVectorStore leaks aiohttp sessions created via get_search_client() #20257

@mangekyousharingan

Description

@mangekyousharingan

Bug Description

When AzureAISearchVectorStore is constructed with BOTH a SearchIndexClient and an AsyncSearchIndexClient that are managed with context managers, the store internally calls:

self._async_search_client = self._async_index_client.get_search_client(index_name)

The AsyncSearchIndexClient context manager cleans up its own aiohttp session on exit, but the AsyncSearchClient returned from get_search_client spins up a new aiohttp.ClientSession/TCPConnector that is never closed.

As a result, the asyncio loop logs:

Asyncio unhandled exception in task 'unknown': Unclosed client session
and
Unclosed connector

To avoid this you have to ad finally block which closes the sessions:

    with SyncSearchIndexClient(endpoint=endpoint, index_name=index_name, credential=creds) as sync_client:
        async with AsyncSearchIndexClient(endpoint=endpoint, index_name=index_name, credential=creds) as async_client:
            vector_store = AzureAISearchVectorStore(
                search_or_index_client=sync_client,
                async_search_or_index_client=async_client,
                index_name=index_name,
                index_management=IndexManagement.CREATE_IF_NOT_EXISTS,
                id_field_key="id",
                chunk_field_key="chunk",
                embedding_field_key="embedding",
                metadata_string_field_key="metadata",
                doc_id_field_key="doc_id",
            )
          
            try:
                yield vector_store
            finally:
                async_search_client = getattr(vector_store, "_async_search_client", None)
                if async_search_client:
                    await async_search_client.close()
  
                search_client = getattr(vector_store, "_search_client", None)
                if search_client:
                    search_client.close()

Version

0.12.52

Steps to Reproduce

from azure.search.documents import SearchIndexClient
from azure.search.documents.indexes import SearchIndexClient as SyncSearchIndexClient
from azure.search.documents.indexes.aio import SearchIndexClient as AsyncSearchIndexClient
from azure.core.credentials import AzureKeyCredential
from llama_index.vector_stores.azureaisearch import AzureAISearchVectorStore, IndexManagement

async def main():
    creds = AzureKeyCredential("<api-key>")
    index_name = "llama-test"
    endpoint = "https://<service-name>.search.windows.net"

    with SyncSearchIndexClient(endpoint=endpoint, index_name=index_name, credential=creds) as sync_client:
        async with AsyncSearchIndexClient(endpoint=endpoint, index_name=index_name, credential=creds) as async_client:
            vector_store = AzureAISearchVectorStore(
                search_or_index_client=sync_client,
                async_search_or_index_client=async_client,
                index_name=index_name,
                index_management=IndexManagement.CREATE_IF_NOT_EXISTS,
                id_field_key="id",
                chunk_field_key="chunk",
                embedding_field_key="embedding",
                metadata_string_field_key="metadata",
                doc_id_field_key="doc_id",
            )
            # use vector_store, e.g. insert nodes

    # Exiting the context emits "Unclosed client session" warnings

Relevant Logs/Tracbacks

Asyncio unhandled exception in task 'unknown' (coro: unknown): Unclosed client session
Asyncio context dump: {'client_session': '<aiohttp.client.ClientSession object at 0xffff674efef0>', 'message': "'Unclosed client session'"}
Asyncio context without exception: {
  'client_session': <aiohttp.client.ClientSession object at 0xffff674efef0>,
  'message': 'Unclosed client session',
  'source_traceback': [
    ...,
    <FrameSummary file /Users/sebix/Repositories/Newcode-Nova-backend/src/app/utils/llama/index.py, line 309 in create_embeddings_from_nodes>,
    <FrameSummary file /usr/local/lib/python3.12/site-packages/llama_index/vector_stores/azureaisearch/base.py, line 965 in async_add>,
    <FrameSummary file /usr/local/lib/python3.12/site-packages/azure/search/documents/aio/_search_client_async.py, line 645 in index_documents>,
    <FrameSummary file /usr/local/lib/python3.12/site-packages/azure/search/documents/aio/_search_client_async.py, line 653 in _index_documents_actions>,
    <FrameSummary file /usr/local/lib/python3.12/site-packages/azure/core/pipeline/_base_async.py, line 229 in run>,
    <FrameSummary file /usr/local/lib/python3.12/site-packages/azure/core/pipeline/_base_async.py, line 77 in send>,
    ...,
    <FrameSummary file /usr/local/lib/python3.12/site-packages/azure/core/pipeline/transport/_aiohttp.py, line 149 in open>
  ]
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtriageIssue needs to be triaged/prioritized

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions