Skip to content

fix: resolve relative cache:// paths to absolute before spawning threads#72

Open
yannrichet-asnr wants to merge 1 commit into
mainfrom
fix/cache-relative-path-threading
Open

fix: resolve relative cache:// paths to absolute before spawning threads#72
yannrichet-asnr wants to merge 1 commit into
mainfrom
fix/cache-relative-path-threading

Conversation

@yannrichet-asnr

Copy link
Copy Markdown
Member

Fixes #71

Problem

run_local_calculation() calls os.chdir() inside worker threads. Since the CWD is process-wide, a relative cache://my-results/ URI evaluated by Path(...).exists() in another thread will return False whenever the CWD has been changed — silently treating every cached case as a miss.

Fix

In fzr(), before handing the calculator list to run_cases_parallel(), resolve every relative cache:// path to an absolute path anchored to original_cwd:

resolved_calculators = []
for calc in calculators:
    if calc.startswith("cache://"):
        cache_path = Path(calc[8:])
        if not cache_path.is_absolute():
            cache_path = Path(original_cwd) / cache_path
        resolved_calculators.append(f"cache://{cache_path.resolve()}")
    else:
        resolved_calculators.append(calc)
calculators = resolved_calculators

This is a single-line-of-user-impact change: absolute cache:// paths are unaffected, relative ones are normalised once on the main thread before any chdir can interfere.

run_local_calculation() calls os.chdir() in worker threads. Since CWD is
process-wide, a relative cache:// URI like cache://my-results/ can silently
fail: Path('my-results/').exists() returns False in any thread that
happens to run after another thread changed the CWD.

Fix: in fzr(), before handing calculators to run_cases_parallel(), resolve
any relative cache:// path against original_cwd so that all threads receive
an absolute URI and Path(...).exists() is CWD-independent.
Copilot AI review requested due to automatic review settings June 15, 2026 12:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a parallel-execution cache miss bug caused by process-wide os.chdir() calls in worker threads, by normalizing cache:// calculator paths to be CWD-independent before launching parallel work.

Changes:

  • Normalize cache://... calculator entries in fzr() so relative cache paths become absolute (anchored to original_cwd) before run_cases_parallel() spawns threads.
  • Add inline documentation explaining the CWD/threading race and why pre-resolution is needed.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread fz/core.py
Comment on lines +1497 to +1504
if calc.startswith("cache://"):
cache_rel = calc[8:]
cache_path = Path(cache_rel)
if not cache_path.is_absolute():
cache_path = Path(original_cwd) / cache_path
resolved_calculators.append(f"cache://{cache_path.resolve()}")
else:
resolved_calculators.append(calc)
Comment thread fz/core.py
Comment on lines +1491 to +1495
# Resolve relative cache:// paths to absolute before spawning threads.
# run_local_calculation() calls os.chdir() in worker threads; since CWD is
# process-wide, a relative cache:// path resolved via Path(...).exists() in
# one thread may fail while another thread has changed the CWD.
resolved_calculators = []
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Relative cache:// path silently fails under parallel execution (threading race on CWD)

2 participants