Skip to content

Conversation

enki
Copy link
Contributor

@enki enki commented Jul 31, 2025

When multiple processes call readCachedProjectGraph() simultaneously before the cache exists, they would all fail with "No cached ProjectGraph is available" error. This leads to a hard to reproduce race condition that has been reported repeatedly.

The fix adds synchronous waiting when a lock file exists, indicating another process is building the graph. Uses Atomics.wait() for efficient blocking without CPU usage.

  • Wait up to 120 seconds for graph to be built (maybe this should be less?)
  • Check every 200ms for graph availability
  • Detect if other process fails (lock removed, no graph)
  • Provide helpful timeout message with lock cleanup instructions

No behavior is changed unless the race condition is encountered (a lockfile exists but no project graph).

Fixes #31648

When multiple processes call readCachedProjectGraph() simultaneously
before the cache exists, they would all fail with "No cached ProjectGraph
is available" error. This was common when running parallel builds.

The fix adds synchronous waiting when a lock file exists, indicating
another process is building the graph. Uses Atomics.wait() for efficient
blocking without CPU usage.

- Wait up to 120 seconds for graph to be built
- Check every 200ms for graph availability
- Detect if other process fails (lock removed, no graph)
- Provide helpful timeout message with lock cleanup instructions

Fixes nrwl#31648

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@enki enki requested a review from a team as a code owner July 31, 2025 07:57
@enki enki requested a review from AgentEnder July 31, 2025 07:57
Copy link

vercel bot commented Jul 31, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
nx-dev ✅ Ready (Inspect) Visit Preview Jul 31, 2025 1:02pm

Copy link
Contributor

nx-cloud bot commented Jul 31, 2025

View your CI Pipeline Execution ↗ for commit ff92b8d

Command Status Duration Result
nx affected --targets=lint,test,build,e2e,e2e-c... ❌ Failed 32m 47s View ↗
nx run-many -t check-imports check-commit check... ✅ Succeeded 2m 10s View ↗
nx-cloud record -- nx-cloud conformance:check ✅ Succeeded 2s View ↗
nx-cloud record -- nx format:check ✅ Succeeded 6s View ↗
nx-cloud record -- nx sync:check ✅ Succeeded 6s View ↗
nx documentation ✅ Succeeded 24s View ↗

☁️ Nx Cloud last updated this comment at 2025-07-31 13:28:16 UTC

projectGraphCache = readProjectGraphCache(minimumComputedAt);

// Check if lock still exists
if (!fileExists(lockPath)) {
Copy link
Member

Choose a reason for hiding this comment

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

The presence of the lock file doesn't actually indicate the graph building. After the first graph is created, the file will always remain on disk. We place an OS read write lock on the file which is the actual indicator

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@AgentEnder That's super helpful! So is the correct approach to add wait_sync to FileLock and update readCachedProjectGraph to use it? (this mirrors createProjectGraphAsync logic but sync)

If so I can supply a PR later today

(we're still encountering #31648 in production so are in need of a fix)

…OOO/nx into fix/project-graph-race-condition-v2
Copy link
Contributor

github-actions bot commented Aug 6, 2025

This pull request has already been merged/closed. If you experience issues related to these changes, please open a new issue referencing this pull request.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 6, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[readCachedProjectGraph] ERROR: No cached ProjectGraph is available

2 participants