Skip to content

Commit c752c84

Browse files
Handle error if cached file was deleted concurrently
Wrap cache file read in try-except to handle race condition where another async task deletes the file between validation and lock acquisition. Automatically retry with force=True to trigger re-download. Signed-off-by: Marcel Bochtler <[email protected]>
1 parent db4b3c1 commit c752c84

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

src/python_inspector/utils_pypi.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1760,9 +1760,24 @@ async def get(
17601760
else:
17611761
if TRACE_DEEP:
17621762
print(f" FILE CACHE HIT: {path_or_url}")
1763-
# also lock on read to avoid race conditions
1764-
with lockfile.FileLock(lock_file).locked(timeout=PYINSP_CACHE_LOCK_TIMEOUT):
1765-
return await get_local_file_content(path=cached, as_text=as_text), cached
1763+
1764+
# File passed validation, lock and read
1765+
# Handle race condition where file might be deleted between validation and lock
1766+
try:
1767+
with lockfile.FileLock(lock_file).locked(timeout=PYINSP_CACHE_LOCK_TIMEOUT):
1768+
return await get_local_file_content(path=cached, as_text=as_text), cached
1769+
except FileNotFoundError:
1770+
# File was deleted by another task after validation - retry with force.
1771+
if TRACE_DEEP:
1772+
print(f" FILE VANISHED after validation, re-downloading: {path_or_url}")
1773+
return await self.get(
1774+
credentials=credentials,
1775+
path_or_url=path_or_url,
1776+
as_text=as_text,
1777+
force=True,
1778+
verbose=verbose,
1779+
echo_func=echo_func,
1780+
)
17661781

17671782

17681783
CACHE = Cache()

0 commit comments

Comments
 (0)