Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions sqlmesh/utils/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,13 @@ def __init__(self, path: Path, prefix: t.Optional[str] = None):
# the file.stat() call below will fail on windows if the :file name is longer than 260 chars
file = fix_windows_path(file)

if not file.stem.startswith(self._cache_version) or file.stat().st_atime < threshold:
file.unlink(missing_ok=True)
try:
stat_result = file.stat()
if not file.stem.startswith(self._cache_version) or stat_result.st_atime < threshold:
file.unlink(missing_ok=True)
except FileNotFoundError:
# File was deleted between glob() and stat() — skip stale cache entries gracefully
continue

def get_or_load(self, name: str, entry_id: str = "", *, loader: t.Callable[[], T]) -> T:
"""Returns an existing cached entry or loads and caches a new one.
Expand Down
21 changes: 21 additions & 0 deletions tests/utils/test_cache.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import os
import time
import typing as t
from pathlib import Path

Expand Down Expand Up @@ -131,3 +133,22 @@ def test_optimized_query_cache_macro_def_change(tmp_path: Path, mocker: MockerFi
new_model.render_query_or_raise().sql()
== 'SELECT "_0"."a" AS "a" FROM (SELECT 1 AS "a") AS "_0" WHERE "_0"."a" = 2'
)


def test_file_cache_init_handles_stale_file(tmp_path: Path, mocker: MockerFixture) -> None:
cache: FileCache[_TestEntry] = FileCache(tmp_path)

stale_file = tmp_path / f"{cache._cache_version}__fake_deleted_model_9999999999"
stale_file.touch()

original_stat = Path.stat

def flaky_stat(self, **kwargs):
if self.name == stale_file.name:
raise FileNotFoundError(f"Simulated stale file: {self}")
return original_stat(self, **kwargs)

mocker.patch.object(Path, "stat", flaky_stat)

FileCache(tmp_path)