fix(redis_cache.py): support pipeline redis lpop for older redis vers… (#11425)

* fix(redis_cache.py): support pipeline redis lpop for older redis versions

Fixes https://github.com/BerriAI/litellm/issues/10379

* test: add mock host
This commit is contained in:
Krish Dholakia 2025-06-05 00:05:54 -07:00 • committed by GitHub
parent a301ef873e
commit db23016536
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 57 additions and 1 deletions

View file

@ -1122,6 +1122,21 @@ class RedisCache(BaseCache):
)
raise e
async def handle_lpop_count_for_older_redis_versions(
self, pipe: pipeline, key: str, count: int
) -> List[bytes]:
result: List[bytes] = []
for _ in range(count):
pipe.lpop(key)
results = await pipe.execute()
# Filter out None values and decode bytes
for r in results:
if r is not None:
result.append(r)
return result
async def async_lpop(
self,
key: str,
@ -1133,7 +1148,22 @@ class RedisCache(BaseCache):
start_time = time.time()
print_verbose(f"LPOP from Redis list: key: {key}, count: {count}")
try:
result = await _redis_client.lpop(key, count)
major_version: int = 7
# Check Redis version and use appropriate method
if self.redis_version != "Unknown":
# Parse version string like "6.0.0" to get major version
major_version = int(self.redis_version.split(".")[0])
if count is not None and major_version < 7:
# For Redis < 7.0, use pipeline to execute multiple LPOP commands
async with _redis_client.pipeline(transaction=False) as pipe:
result = await self.handle_lpop_count_for_older_redis_versions(
pipe, key, count
)
else:
# For Redis >= 7.0 or when count is None, use native LPOP with count
result = await _redis_client.lpop(key, count)
## LOGGING ##
end_time = time.time()
_duration = end_time - start_time

View file

@ -94,3 +94,29 @@ async def test_redis_cache_async_batch_get_cache(monkeypatch, redis_no_ping):
assert result["key1"] == {"key1": "value1"}
assert result["key2"] is None
assert result["key3"] == {"key3": "value3"}
@pytest.mark.asyncio
async def test_handle_lpop_count_for_older_redis_versions(monkeypatch):
"""Test the helper method that handles LPOP with count for Redis versions < 7.0"""
monkeypatch.setenv("REDIS_HOST", "https://my-test-host")
# Create RedisCache instance
redis_cache = RedisCache()
# Create a mock pipeline
mock_pipeline = AsyncMock()
# Set up execute to return different values each time
mock_pipeline.execute.side_effect = [
[b"value1"], # First execute returns first value
[b"value2"], # Second execute returns second value
]
# Test the helper method
result = await redis_cache.handle_lpop_count_for_older_redis_versions(
pipe=mock_pipeline, key="test_key", count=2
)
# Verify results
assert result == [b"value1", b"value2"]
assert mock_pipeline.lpop.call_count == 2
assert mock_pipeline.execute.call_count == 2