-
Bug
-
Resolution: Unresolved
-
Critical
-
None
The system property jenkins.branch.WorkspaceLocatorImpl$Deleter.CLEANUP_THREAD_LIMIT controls the initial number of permits of a Semaphore. But this value is not limiting the number of threads efficiently because more permits are being accumulating over time.
CleanupTask s are spun up for the built-in node without acquiring a semaphore permit however it will release a permit (create an additional one) :
- https://github.com/jenkinsci/branch-api-plugin/blob/2.1200.v4b_a_3da_2eb_db_4/src/main/java/jenkins/branch/WorkspaceLocatorImpl.java#L398
- https://github.com/jenkinsci/branch-api-plugin/blob/2.1200.v4b_a_3da_2eb_db_4/src/main/java/jenkins/branch/WorkspaceLocatorImpl.java#L532
Note: The amount of permits would increase by one per deleted item.
How to Reproduce
- Create a Jenkins instance with -Djenkins.branch.WorkspaceLocatorImpl\$Deleter.CLEANUP_THREAD_LIMIT=1
- Connect 1 node
- In Manage Jenkins > Script Console, execute jenkins.branch.WorkspaceLocatorImpl.Deleter.cleanupPool.availablePermits() and validate that it shows 1
- Create a Multibranch pipeline with N branches
- Add a filter to have all branches discarded and removed by the orphaned item strategy and save
- In Manage Jenkins > Script Console, execute jenkins.branch.WorkspaceLocatorImpl.Deleter.cleanupPool.availablePermits() ->> it shows a value of 1+N
Further Note
A Semaphore does not keep a particular object for permits, just keep record of a count on acquire / release. Semaphore#acquire wait for a permit and decrement the count. Semaphore#release release a permit and increments the count.
Here we set an initial number (that’s what we control with the system property, the initial number) but *that is not a Maximum*. If we do un-necessary Semaphore#release, we may actually increase the number of permits….
Semaphore mySemaphore = new Semaphore(1, true); // number of available permits = 1 mySemaphore.acquire(); // number of available permits = 0 mySemaphore.release(); // number of available permits = 1 mySemaphore.release(); // number of available permits = 2
+1 - We have been dealing with this exact issue for some time as well and critically need it resolved