diff --git a/litellm/caching/redis_cache.py b/litellm/caching/redis_cache.py index 6bb5801f9a9..5339719c016 100644 --- a/litellm/caching/redis_cache.py +++ b/litellm/caching/redis_cache.py @@ -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 diff --git a/tests/test_litellm/caching/test_redis_cache.py b/tests/test_litellm/caching/test_redis_cache.py index 447b0a3bbd3..654645548ff 100644 --- a/tests/test_litellm/caching/test_redis_cache.py +++ b/tests/test_litellm/caching/test_redis_cache.py @@ -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