-
Notifications
You must be signed in to change notification settings - Fork 2.7k
fix(core): share visited Set across affected graph traversal #33756
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(core): share visited Set across affected graph traversal #33756
Conversation
Previously, filterAffectedProjects created a NEW visited Set for each touched project, defeating the purpose of deduplication. If projects A and B both depend on shared project C, C would be visited twice. Now uses shared visited Sets across all touched projects, reducing redundant traversal from O(touchedProjects × sharedDeps) to O(nodes).
👷 Deploy request for nx-docs pending review.Visit the deploys page to approve it
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
View your CI Pipeline Execution ↗ for commit 9bf3b58
☁️ Nx Cloud last updated this comment at |
leosvelperez
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nx Cloud has identified a possible root cause for your failed CI:
Our tests are failing due to an external infrastructure issue: the Foojay resolver service (used by Gradle to provision Java toolchains) is returning 503 Service Temporarily Unavailable errors. The similar-task-failure-detector confirmed this same error exists in the master branch, proving it's unrelated to our PR's changes to affected graph traversal logic. We need to wait for the Foojay service to recover before these e2e tests can pass.
No code changes were suggested for this issue.
If the issue was transient, you can trigger a rerun by pushing an empty commit:
git commit --allow-empty -m "chore: trigger rerun"
git push
🎓 Learn more about Self-Healing CI on nx.dev
## Current Behavior
In `filterAffectedProjects`, a **new visited Set is created for each
touched project**:
```typescript
ctx.touchedProjects.forEach((p) => {
addAffectedNodes(p, reversed, result, new Set()); // NEW Set per project!
});
ctx.touchedProjects.forEach((p) => {
addAffectedDependencies(p, reversed, result, new Set()); // NEW Set per project!
});
```
This defeats the purpose of the visited Set for deduplication. If
projects A and B both depend on shared project C, then C gets visited
**twice**.
## Expected Behavior
Share a single visited Set across all touched projects:
```typescript
const visitedNodes = new Set<string>();
const visitedDeps = new Set<string>();
for (const p of ctx.touchedProjects) {
addAffectedNodes(p, reversed, result, visitedNodes); // SHARED Set
}
for (const p of ctx.touchedProjects) {
addAffectedDependencies(p, reversed, result, visitedDeps); // SHARED Set
}
```
## Performance Impact
```
Before (separate Sets): After (shared Sets):
┌─────────────────────────┐ ┌─────────────────────────┐
│ touchedProjects: [A,B] │ │ touchedProjects: [A,B] │
└───────────┬─────────────┘ └───────────┬─────────────┘
│ │
┌───────┴───────┐ ┌───────┴───────┐
▼ ▼ ▼ ▼
┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐
│ A │ │ B │ │ A │ │ B │
│visited│ │visited│ │ │ │ │
│= {} │ │= {} │ │ shared visitedNodes │
└───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘
│ │ │ │
▼ ▼ ▼ ▼
┌───────┐ ┌───────┐ ┌───────────────────────┐
│visit C│ │visit C│ │ visit C (ONCE) │
│(dup!) │ │(dup!) │ │ skip C from B │
└───────┘ └───────┘ └───────────────────────┘
Complexity: Complexity:
O(touched × shared_deps) O(total_nodes)
```
**Example**: With 50 touched projects sharing 100 common dependencies:
- Before: 50 × 100 = 5,000 node visits
- After: ~150 node visits (each node visited once)
## Why Accept This PR
1. **Bug-like behavior**: The current code defeats the purpose of the
visited Set
2. **Significant impact**: Affects every `nx affected` command
3. **Zero risk**: Same traversal logic, just shared deduplication
4. **Common scenario**: Monorepos often have shared dependencies (utils,
types, etc.)
## Related Issue(s)
Contributes to #32265
## Merge Dependencies
This PR has no dependencies and can be merged independently.
---
Co-authored-by: Leosvel Pérez Espinosa <[email protected]>
|
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. |
Current Behavior
In
filterAffectedProjects, a new visited Set is created for each touched project:This defeats the purpose of the visited Set for deduplication. If projects A and B both depend on shared project C, then C gets visited twice.
Expected Behavior
Share a single visited Set across all touched projects:
Performance Impact
Example: With 50 touched projects sharing 100 common dependencies:
Why Accept This PR
nx affectedcommandRelated Issue(s)
Contributes to #32265
Merge Dependencies
This PR has no dependencies and can be merged independently.