fix: remove cache eviction close that kills in-use httpx clients

This commit is contained in:
Ryan Crabbe
2026-02-26 17:39:01 -08:00
parent 5a95d9beee
commit df36845839
2 changed files with 0 additions and 55 deletions
-19
View File
@@ -8,25 +8,6 @@ from .in_memory_cache import InMemoryCache
class LLMClientCache(InMemoryCache):
def _remove_key(self, key: str) -> None:
"""Close async clients before evicting them to prevent connection pool leaks."""
value = self.cache_dict.get(key)
super()._remove_key(key)
if value is not None:
close_fn = getattr(value, "aclose", None) or getattr(
value, "close", None
)
if close_fn and asyncio.iscoroutinefunction(close_fn):
try:
asyncio.get_running_loop().create_task(close_fn())
except RuntimeError:
pass
elif close_fn and callable(close_fn):
try:
close_fn()
except Exception:
pass
def update_cache_key_with_event_loop(self, key):
"""
Add the event loop to the cache key, to prevent event loop closed errors.
@@ -4,14 +4,12 @@ Regression tests for Redis connection pool leak fixes (RC1-RC5).
Tests are pure unit tests — no Redis server required.
"""
import asyncio
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
import redis.asyncio as async_redis
from litellm._redis import get_redis_async_client, get_redis_connection_pool
from litellm.caching.llm_caching_handler import LLMClientCache
def test_url_config_uses_passed_pool():
@@ -131,37 +129,3 @@ async def test_disconnect_idempotent():
await cache.disconnect() # should not raise
@pytest.mark.asyncio
async def test_eviction_calls_aclose():
"""When an async client is evicted from LLMClientCache, its aclose()
should be scheduled via create_task."""
cache = LLMClientCache(max_size_in_memory=2, default_ttl=600)
client = AsyncMock()
client.aclose = AsyncMock()
cache.set_cache(key="client-0", value=client)
cache.set_cache(key="filler", value="x")
# Third insert triggers eviction of client-0
cache.set_cache(key="trigger", value="y")
# Let the scheduled task run
await asyncio.sleep(0.05)
assert client.aclose.await_count > 0
@pytest.mark.asyncio
async def test_eviction_non_closeable_safe():
"""Evicting plain values (strings, dicts, ints) should not crash."""
cache = LLMClientCache(max_size_in_memory=2, default_ttl=600)
cache.set_cache(key="str-val", value="hello")
cache.set_cache(key="dict-val", value={"foo": "bar"})
# This evicts "str-val" — should not raise
cache.set_cache(key="int-val", value=42)
await asyncio.sleep(0.05)
# If we got here without exception, the test passes
assert cache.get_cache(key="int-val") == 42