Improve cycle detection when constructing the dependency graph#11575
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #11575 +/- ##
============================================
+ Coverage 58.38% 58.41% +0.03%
- Complexity 1754 1761 +7
============================================
Files 355 355
Lines 13211 13222 +11
Branches 1313 1314 +1
============================================
+ Hits 7713 7724 +11
Misses 5008 5008
Partials 490 490
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
73735ab to
69f5230
Compare
|
This is also related to #11426. I am not sure about the failing fun test for cocoapods; this may be related to the changes or not. Would need to test this locally, but would need to set up cocoapods first. |
|
With this, would the |
I am not sure about this. This PR prevents a stack overflow when constructing a dependency graph with cyclic dependencies. But obviously, this logic was introduced in the past to handle cycles in graphs that could be constructed successfully. So maybe there are constellations that still lead to such cycles. |
I could run |
I've retriggered the test run to verify. |
Well, my point is that the existing logic maybe only had to be introduced because we did not have the (more general?) checks from this PR.
We should try to find our what those "constellations" are, if any. Do we trust our existing test coverage in that area enough to say that if with |
This time, there are other test failures :-/ |
I would support this, but I do not why this logic was added initially; were there concrete issues or was this a more theoretical exercise? The code is from @fviernau - do you remember? Regarding test coverage, I have my doubts, since it is very difficult to simulate such scenarios - in this PR I had to do some tricks with spies. And the functional tests are probably not complex enough. |
While |
|
This is indeed strange. Does the test really fail on each run? There were also runs showing other test failures. My local execution of the test was quite fast. |
Maybe not on every run, but I've retriggered the test at least 5 times yesterday, and no run was without (some) failure.
I guess that depends on your definition of "fast" 😅 On |
|
The culprit seems to be the change in |
69f5230 to
e008ffd
Compare
|
The current version of this fix is working as expected now. Running |
Could you please share more details about what caused the previous problem, and how it's being solved now? I'm curious, esp. about why |
|
When checking for the equality of dependencies, the previous version of the check had this code to check the transitive dependencies: This obviously caused numerous recursive calls, even if the currently processed nodes have already been encountered before. This has now been replaced with this code: Here no recursion is started if both nodes have already been processed before; so, the cycle is broken early. The problems with |
| val transitiveDependencies = dependencyHandler.dependenciesFor(dependency).mapNotNullTo(mutableSetOf()) { | ||
| addDependencyToGraph(scopeName, it, transitive = true, processed) | ||
| } | ||
| val nextProcessed = processed + dependency |
There was a problem hiding this comment.
Commit message:
its own set of transitive dependencies.
I'm wondering, shouldn't this say "direct dependencies"? I though the special case of a cycle that's being fixed here is when the cycle is "as tight as it can be", with a dependency pointing directly to itself.
If the above is not correct, could you make more clear in the commit message how this type of cycle differs from the type of cycles that were already handled before this change?
There was a problem hiding this comment.
Actually, this fix does not handle new types of cyclic dependencies. It just executes the check to detect cycles at a different time. The original problem was that this check came too late and therefore did not prevent the stack overflow.
There was a problem hiding this comment.
Could you add the above to the first commit's message then, removing most of its current content? To me, this explanation is much clearer.
There was a problem hiding this comment.
Changed the commit message.
There was a problem hiding this comment.
The original problem was that this check came too late and therefore did not prevent the stack overflow.
For reference, this confirms what I had assumed already back here.
Improve the detection of cycles in the dependency graph when adding dependencies. Move the already existing check for cycles, so that it gets executed earlier before entering the recursive handling of transitive dependencies. In the original code, this check happened too late and did not prevent a stack overflow error, which was reported in a Yarn2 project. Signed-off-by: Oliver Heger <[email protected]>
The `areDependenciesEqual()` function could run in a stack overflow if the graphs to be compared contained cycles. Fix this by keeping track of the nodes that have been processed. Signed-off-by: Oliver Heger <[email protected]>
e008ffd to
c988bd9
Compare
This PR contains two fixes for potential stack overflow errors that might occur during construction of the dependency graph when there are cycles in dependencies. The errors were observed in practice in a Yarn2 project. This is probably related to #11524.