-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CV2-4719 initial idea saround caching layer in presto
- Loading branch information
Showing
4 changed files
with
110 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import redis | ||
import json | ||
from typing import Any, Optional | ||
from lib.helpers import get_environment_setting | ||
|
||
REDIS_URL = get_environment_setting("REDIS_URL") | ||
DEFAULT_TTL = int(get_environment_setting("CACHE_DEFAULT_TTL") or 24*60*60) | ||
class Cache: | ||
@staticmethod | ||
def get_client() -> redis.Redis: | ||
""" | ||
Get a Redis client instance using the provided REDIS_URL. | ||
Returns: | ||
redis.Redis: Redis client instance. | ||
""" | ||
return redis.Redis.from_url(REDIS_URL) | ||
|
||
@staticmethod | ||
def get_cached_result(content_hash: str, reset_ttl: bool = True, ttl: int = DEFAULT_TTL) -> Optional[Any]: | ||
""" | ||
Retrieve the cached result for the given content hash. By default, reset the TTL to 24 hours. | ||
Args: | ||
content_hash (str): The key for the cached content. | ||
reset_ttl (bool): Whether to reset the TTL upon access. Default is True. | ||
ttl (int): Time-to-live for the cache in seconds. Default is 86400 seconds (24 hours). | ||
Returns: | ||
Optional[Any]: The cached result, or None if the key does not exist. | ||
""" | ||
client = Cache.get_client() | ||
cached_result = client.get(content_hash) | ||
if cached_result is not None: | ||
if reset_ttl: | ||
client.expire(content_hash, ttl) | ||
return json.loads(cached_result) | ||
return None | ||
|
||
@staticmethod | ||
def set_cached_result(content_hash: str, result: Any, ttl: int = DEFAULT_TTL) -> None: | ||
""" | ||
Store the result in the cache with the given content hash and TTL. | ||
Args: | ||
content_hash (str): The key for the cached content. | ||
result (Any): The result to cache. | ||
ttl (int): Time-to-live for the cache in seconds. Default is 86400 seconds (24 hours). | ||
""" | ||
client = Cache.get_client() | ||
client.setex(content_hash, ttl, json.dumps(result)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import pytest | ||
from unittest.mock import patch, MagicMock | ||
from lib.cache import Cache | ||
|
||
# Mock the Redis client and its methods | ||
@pytest.fixture | ||
def mock_redis_client(): | ||
with patch('lib.cache.redis.Redis') as mock_redis: | ||
yield mock_redis | ||
|
||
def test_set_cached_result(mock_redis_client): | ||
mock_instance = mock_redis_client.from_url.return_value | ||
content_hash = "test_hash" | ||
result = {"data": "example"} | ||
ttl = 3600 | ||
|
||
Cache.set_cached_result(content_hash, result, ttl) | ||
|
||
mock_instance.setex.assert_called_once_with(content_hash, ttl, '{"data": "example"}') | ||
|
||
def test_get_cached_result_exists(mock_redis_client): | ||
mock_instance = mock_redis_client.from_url.return_value | ||
content_hash = "test_hash" | ||
ttl = 3600 | ||
cached_data = '{"data": "example"}' | ||
mock_instance.get.return_value = cached_data | ||
|
||
result = Cache.get_cached_result(content_hash, reset_ttl=True, ttl=ttl) | ||
|
||
assert result == {"data": "example"} | ||
mock_instance.expire.assert_called_once_with(content_hash, ttl) | ||
|
||
def test_get_cached_result_not_exists(mock_redis_client): | ||
mock_instance = mock_redis_client.from_url.return_value | ||
content_hash = "test_hash" | ||
mock_instance.get.return_value = None | ||
|
||
result = Cache.get_cached_result(content_hash) | ||
|
||
assert result is None | ||
mock_instance.expire.assert_not_called() | ||
|
||
def test_get_cached_result_no_ttl_reset(mock_redis_client): | ||
mock_instance = mock_redis_client.from_url.return_value | ||
content_hash = "test_hash" | ||
cached_data = '{"data": "example"}' | ||
mock_instance.get.return_value = cached_data | ||
|
||
result = Cache.get_cached_result(content_hash, reset_ttl=False) | ||
|
||
assert result == {"data": "example"} | ||
mock_instance.expire.assert_not_called() |