mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-14 23:21:35 +00:00
fix(redis_cache): apply namespace in delete_cache and async_delete_cache
When a Redis namespace is configured, SET and GET correctly prefix the key via check_and_fix_namespace, but DELETE did not — causing the PodLockManager to always target a non-existent key and never explicitly release locks (they would expire by TTL instead, with a warning on every cycle). Adds check_and_fix_namespace to both async_delete_cache and delete_cache, and covers both paths with a parametrized unit test (namespace=None / "myns").
This commit is contained in:
parent
3e1479c052
commit
62473fc4ff
2 changed files with 29 additions and 3 deletions
|
|
@ -1259,10 +1259,11 @@ class RedisCache(BaseCache):
|
|||
async def async_delete_cache(self, key: str):
|
||||
# typed as Any, redis python lib has incomplete type stubs for RedisCluster and does not include `delete`
|
||||
_redis_client: Any = self.init_async_client()
|
||||
# keys is str
|
||||
key = self.check_and_fix_namespace(key=key)
|
||||
return await _redis_client.delete(key)
|
||||
|
||||
def delete_cache(self, key):
|
||||
def delete_cache(self, key: str):
|
||||
key = self.check_and_fix_namespace(key=key)
|
||||
self.redis_client.delete(key)
|
||||
|
||||
async def _pipeline_increment_helper(
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import sys
|
|||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
sys.path.insert(
|
||||
0, os.path.abspath("../../..")
|
||||
|
|
@ -473,3 +472,29 @@ async def test_async_lpop_with_float_redis_version(
|
|||
|
||||
# Verify the method completed without error
|
||||
assert result is not None
|
||||
|
||||
|
||||
@pytest.mark.parametrize("namespace", [None, "myns"])
|
||||
@pytest.mark.asyncio
|
||||
async def test_delete_cache_applies_namespace(namespace, monkeypatch, redis_no_ping):
|
||||
"""async_delete_cache and delete_cache must apply the namespace prefix so that
|
||||
DEL targets the same key that SET/GET use."""
|
||||
monkeypatch.setenv("REDIS_HOST", "https://my-test-host")
|
||||
redis_cache = RedisCache(namespace=namespace)
|
||||
|
||||
raw_key = "cronjob_lock:db_spend_update_job"
|
||||
expected_key = f"{namespace}:{raw_key}" if namespace else raw_key
|
||||
|
||||
# --- async path ---
|
||||
mock_async_client = AsyncMock()
|
||||
with patch.object(
|
||||
redis_cache, "init_async_client", return_value=mock_async_client
|
||||
):
|
||||
await redis_cache.async_delete_cache(key=raw_key)
|
||||
mock_async_client.delete.assert_called_once_with(expected_key)
|
||||
|
||||
# --- sync path ---
|
||||
mock_sync_client = MagicMock()
|
||||
redis_cache.redis_client = mock_sync_client
|
||||
redis_cache.delete_cache(key=raw_key)
|
||||
mock_sync_client.delete.assert_called_once_with(expected_key)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue