Skip to content

Commit f3eaf00

Browse files
committed
DATASHADES-321 / fix file ttl invalidaton, add more tests
1 parent a98d8bf commit f3eaf00

File tree

2 files changed

+46
-13
lines changed

2 files changed

+46
-13
lines changed

ckanext/charts/cache.py

+16-11
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,8 @@ def __init__(self):
7474

7575
def get_data(self, key: str) -> pd.DataFrame | None:
7676
"""Return data from cache if exists"""
77-
file_path = os.path.join(
78-
self.directory, f"{self.generate_unique_consistent_filename(key)}.orc"
79-
)
77+
78+
file_path = self.make_file_path_from_key(key)
8079

8180
if os.path.exists(file_path):
8281
if self.is_file_cache_expired(file_path):
@@ -89,21 +88,22 @@ def get_data(self, key: str) -> pd.DataFrame | None:
8988

9089
def set_data(self, key: str, data: pd.DataFrame) -> None:
9190
"""Save data to cache. The data will be stored as an ORC file."""
92-
file_path = os.path.join(
93-
self.directory, f"{self.generate_unique_consistent_filename(key)}.orc"
94-
)
91+
file_path = self.make_file_path_from_key(key)
9592

9693
data.to_orc(file_path)
9794

9895
def invalidate(self, key: str) -> None:
9996
"""Remove data from cache"""
100-
file_path = os.path.join(
101-
self.directory, f"{self.generate_unique_consistent_filename(key)}.orc"
102-
)
97+
file_path = self.make_file_path_from_key(key)
10398

10499
if os.path.exists(file_path):
105100
os.remove(file_path)
106101

102+
def make_file_path_from_key(self, key: str) -> str:
103+
return os.path.join(
104+
self.directory, f"{self.generate_unique_consistent_filename(key)}.orc"
105+
)
106+
107107
def generate_unique_consistent_filename(self, key: str) -> str:
108108
"""Generate unique and consistent filename based on the key"""
109109
hash_object = hashlib.sha256()
@@ -112,8 +112,13 @@ def generate_unique_consistent_filename(self, key: str) -> str:
112112

113113
@staticmethod
114114
def is_file_cache_expired(file_path: str) -> bool:
115-
"""Check if file cache is expired"""
116-
return os.path.getmtime(file_path) + config.get_file_cache_ttl() < time.time()
115+
"""Check if file cache is expired. If TTL is 0 then cache never expires."""
116+
file_ttl = config.get_file_cache_ttl()
117+
118+
if not file_ttl:
119+
return False
120+
121+
return time.time() - os.path.getmtime(file_path) > file_ttl
117122

118123

119124
def get_cache_manager(cache_strategy: str | None) -> CacheStrategy:

ckanext/charts/tests/test_cache.py

+30-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
from ckan.tests.helpers import call_action
77

88
import ckanext.charts.fetchers as fetchers
9+
import ckanext.charts.cache as cache
910
import ckanext.charts.tests.helpers as helpers
1011
import ckanext.charts.const as const
12+
import ckanext.charts.config as config
1113

1214

1315
@pytest.mark.ckan_config("ckan.plugins", "charts_view datastore")
@@ -188,8 +190,30 @@ def test_invalidate_file_cache(self):
188190
assert fetcher.get_cached_data() is None
189191

190192

191-
class TestCalculateFileCacheTTL:
192-
def test_calculate_file_cache_ttl(self):
193+
from freezegun import freeze_time
194+
from datetime import timedelta, datetime
195+
196+
197+
@pytest.mark.usefixtures("clean_file_cache")
198+
@pytest.mark.ckan_config(config.CONF_FILE_CACHE_TTL, 100)
199+
class TestCalculateFileExpiration:
200+
def test_file_is_expired(self):
201+
fetcher = fetchers.FileSystemDataFetcher(
202+
helpers.get_file_path("sample.csv"), cache_strategy=const.CACHE_FILE
203+
)
204+
205+
assert fetcher.get_cached_data() is None
206+
207+
fetcher.fetch_data()
208+
209+
assert isinstance(fetcher.get_cached_data(), pd.DataFrame)
210+
211+
file_path = cache.FileCache().make_file_path_from_key(fetcher.make_cache_key())
212+
213+
with freeze_time(datetime.now() + timedelta(seconds=101)):
214+
assert cache.FileCache().is_file_cache_expired(file_path)
215+
216+
def test_file_is_not_expired(self):
193217
fetcher = fetchers.FileSystemDataFetcher(
194218
helpers.get_file_path("sample.csv"), cache_strategy=const.CACHE_FILE
195219
)
@@ -199,3 +223,7 @@ def test_calculate_file_cache_ttl(self):
199223
fetcher.fetch_data()
200224

201225
assert isinstance(fetcher.get_cached_data(), pd.DataFrame)
226+
227+
file_path = cache.FileCache().make_file_path_from_key(fetcher.make_cache_key())
228+
229+
assert not cache.FileCache().is_file_cache_expired(file_path)

0 commit comments

Comments
 (0)