ensure shutdown of the symlink planting pool#28657
ensure shutdown of the symlink planting pool#28657benjaminp wants to merge 1 commit intobazelbuild:masterfrom
Conversation
There was a problem hiding this comment.
Code Review
This pull request addresses a resource leak where the symlink planting thread pool was not being shut down, leading to sluggishness in Bazel. The fix introduces a more robust shutdown mechanism by calling a new shutdown() method from a finally block, ensuring the thread pool is always released. The changes in ExecutionTool.java correctly plumb the IncrementalPackageRoots instance to the finalization logic. My review includes one high-severity comment on a potential race condition in the new shutdown() method in IncrementalPackageRoots.java.
3f70379 to
dc76b37
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request addresses a resource leak by ensuring the symlink planting thread pool is shut down at the end of a build. The changes introduce a shutdown() method and call it from a finally block for robustness. My review focuses on consolidating all related cleanup logic into this new robust shutdown() method to prevent other potential memory leaks on build failure paths.
| public void shutdown() { | ||
| synchronized (symlinkPlantingPool) { | ||
| if (!symlinkPlantingPool.isShutdown()) { | ||
| ExecutorUtil.uninterruptibleShutdownNow(symlinkPlantingPool); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
This new shutdown() method is a great step towards preventing thread leaks. However, other cleanup logic in dropIntermediateStatesAndUnregisterFromEventBus() is only triggered on successful analysis, which can lead to memory leaks on failure paths since this IncrementalPackageRoots instance is retained across builds.
To make the cleanup more robust, I recommend consolidating all cleanup logic from dropIntermediateStatesAndUnregisterFromEventBus() into this shutdown() method, as it's called from a finally block in ExecutionTool. This includes unregistering from the event bus and clearing other state.
public void shutdown() {
if (eventBus != null) {
try {
eventBus.unregister(this);
} catch (IllegalArgumentException e) {
// Already unregistered, ignore.
}
eventBus = null;
}
synchronized (stateLock) {
donePackages = null;
lazilyPlantedSymlinks = null;
maybeConflictingBaseNamesLowercase = ImmutableSet.of();
}
synchronized (symlinkPlantingPool) {
if (!symlinkPlantingPool.isShutdown()) {
ExecutorUtil.uninterruptibleShutdownNow(symlinkPlantingPool);
}
}
}There was a problem hiding this comment.
I believe the assumption that IncrementalPackageRoots is retained across builds is not true.
There was a problem hiding this comment.
It is. Just that it's always replaced by another instance of IncrementalPackageRoots at the beginning of the next build. Feel free to treat that as out of scope for this PR though.
There was a problem hiding this comment.
I suppose it is nicer for the exceptional and successful cleanup logic to be the same. So, I've updated the PR to put all logic in shutdown and also call that on analysis completion.
|
Change looks good to me, but I want Joe to also have a look when he is back next week |
joeleba
left a comment
There was a problem hiding this comment.
LGTM. It's up to you whether you wanna address the suggestion by gemini.
dc76b37 to
956e4e7
Compare
I was iteratively fixing some build failures with bazel and realized bazel was becoming more and more sluggish. Taking a thread dump, I observed way too many symlink planting threads: ``` $ grep -c 'Non-eager Symlink planter ' stacks.txt 36800 ``` Try harder to ensure the symlink planting thread pool is released after the build is done.
956e4e7 to
79991b6
Compare
I was iteratively fixing some build failures with bazel and realized bazel was becoming more and more sluggish. Taking a thread dump, I observed way too many symlink planting threads:
Try harder to ensure the symlink planting thread pool is released after the build is done.