[7.2.0] Fix a race condition in IncrementalPackageRoots. #22127
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Consider the following scenario:
A
andB
A
, we need to plant symlinks forNestedSet<Package>: [A1, C1, [D1]]
,B
, we need to plant symlinks forNestedSet<Package>: [B1, C1, [D1]]
In the end, we expect to see symlinks to
A1
,B1
,C1
andD1
.What went wrong
With the current code, there are 2 possible race conditions:
A
NestedSet [D1]
added tohandledPackageNestedSets
. No symlink planted yet.B
NestedSet [D1]
seen as "handled" and immediately skipped. PlantedB1
andC1
.B
moves on to execution.=> actions from
B
that requiresD1
would fail (no such file or directory).A
C1
added tolazilyPlantedSymlinks
. No symlink planted yet.B
C1
already seen inlazilyPlantedSymlinks
and immediately skipped. PlantedB1
andD1
.B
moves on to execution.=> actions from
B
that requiresC1
would fail (no such file or directory).The Solution
In order to prevent this race condition, we can plant the symlinks for top level targets
A
andB
sequentially. This gives us the guarantee that: for an actionfoo
under a top level targetA
,foo
is only executed when all the necessary symlinks forA
are already planted.The above scenario would look like:
A
TopLevelTargetReadyForSymlinkPlanting
event forB
arrived and is held in the sequential event queuelazilyPlantedSymlinks: [A1, C1, D1]
.A
moves on to execution.B
NestedSet [D1]
already seen inhandledPackageNestedSets
and immediately skipped.C1
already seen inlazilyPlantedSymlinks
and immediately skipped.B1
.B
moves on to execution.As an (hopefully not premature) optimization, the symlinks under a single top level target are planted in parallel.
Fixes #22073
Verified locally with something similar to the repro in #22073 (comment).
PiperOrigin-RevId: 628080361
Change-Id: Ic6c1a6606d26400c46aa98bfeddc844abd075d0a
Commit 52adf0b