-
Notifications
You must be signed in to change notification settings - Fork 258
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
[Bug]: Very slow restore or OOM when using NoWarn #11669
Comments
We'd be happy to take a fix for this @mjolka |
I see that there hasn't been a PR for this, so I'm submitting one. This probably doesn't have a substantial performance impact - I was not able to reproduce the significant slowness reported in @mjolka's LotsOfDependenciesIntersect solution. Perhaps that was remedied by the fix for #11222. Edit: it has a performance impact in the form of memory utilization, it just isn't as striking as in #11222. |
Hello @erdembayar, |
It's bit too early to say when it would be released. Most likely it would be released with nuget 6.3. |
@bouchraRekhadda We'll set the |
Alright, thank you @nkolev92 and @erdembayar |
NuGet Product Used
dotnet.exe, NuGet.exe
Product Version
6.1.0.106
Worked before?
No response
Impact
I'm unable to use this version
Repro Steps & Context
Description
A NoWarn in a package reference can add minutes to a restore, or make it fail with an
OutOfMemoryException
.This is related to #11222 and NuGet/NuGet.Client#4475.
Background
TransitiveNoWarnUtils
performs a breadth-first traversal of the dependency graph.The first time we find a path from the root node to a project node
v
, we store the union of the NoWarns seen along the path in a dictionary calledseen
.Each subsequent time we find a path from the root node to
v
, we check if the NoWarns seen along the new path tov
are a superset ofseen[v]
.If that's the case, we don't need to process the node again.
If that's not the case, we update
seen[v]
to be the intersection ofseen[v]
and the NoWarns seen along the new path tov
.There is a bug in the method for finding the intersection that causes nodes to be processed more often than they should be. As a consequence, a single NoWarn can add minutes to a project restore, or cause the restore to fail with an
OutOfMemoryException
.In the method for checking whether the NoWarns along one path are a superset of the NoWarns along another path (
NodeWarningProperties.IsSubSetOf
),null
is considered to be the empty set.The bug is this: in the method to get the intersection of the NoWarns (
NodeWarningProperties.GetIntersect
),null
doesn't act like the empty set.Steps to reproduce
To reproduce this issue, create n >= 30 projects - where
ClassLibrary{i}
has project references toClassLibary1
..ClassLibrary{i-1}
.In addition, create three more projects:
Root
,RootLeft
, andRootRight
with the following project references:Add the following two package references to
RootLeft
:(Code to create all these projects can be found here: https://github.com/mjolka/LotsOfDependenciesIntersect)
The single nowarn in
RootLeft
causes the package restore to go from ~3 seconds to ~7 minutes when n = 30.When n = 35, the restore fails with an
OutOfMemoryException
.The reason being, all
ClassLibrary{i}
projects are found first via a path that goes throughRootLeft
. This path contains a single NoWarn.When
ClassLibrary{i}
is later found via a path that goes throughRootRight
, these are no NoWarns along the path. The code to calculate the intersection of the NoWarns should result in the empty set. However, because of the bug, after taking the intersection,seen[v]
still contains a single NoWarn, and the node will be processed again each time we find a new path to it.The fix is to align the behaviour of
GetIntersect
to that ofIsSubSetOf
by treatingnull
as the empty set. I'm able to contribute a pull request with this change.Verbose Logs
No response
The text was updated successfully, but these errors were encountered: