-
Bug
-
Resolution: Fixed
-
Critical
-
None
-
-
branch-api:2.1214.v3f652804588d
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
[JENKINS-74975] WorkspaceLocatorImpl$Deleter.CLEANUP_THREAD_LIMIT is not effective
Description |
Original:
The system property {{jenkins.branch.WorkspaceLocatorImpl$Deleter.CLEANUP_THREAD_LIMIT}} controls the initial number of permits of a [Semaphore|https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/Semaphore.html]. 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}} 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 ### 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…. {code} 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 {code} |
New:
The system property {{jenkins.branch.WorkspaceLocatorImpl$Deleter.CLEANUP_THREAD_LIMIT}} controls the initial number of permits of a [Semaphore|https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/Semaphore.html]. 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}} 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 h3. 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…. {code} 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 {code} |
Description |
Original:
The system property {{jenkins.branch.WorkspaceLocatorImpl$Deleter.CLEANUP_THREAD_LIMIT}} controls the initial number of permits of a [Semaphore|https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/Semaphore.html]. 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}} 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 h3. 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…. {code} 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 {code} |
New:
The system property {{jenkins.branch.WorkspaceLocatorImpl$Deleter.CLEANUP_THREAD_LIMIT}} controls the initial number of permits of a [Semaphore|https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/Semaphore.html]. 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}} 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 h3. 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…. {code} 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 {code} |
Description |
Original:
The system property {{jenkins.branch.WorkspaceLocatorImpl$Deleter.CLEANUP_THREAD_LIMIT}} controls the initial number of permits of a [Semaphore|https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/Semaphore.html]. 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}} 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 h3. 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…. {code} 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 {code} |
New:
The system property {{jenkins.branch.WorkspaceLocatorImpl$Deleter.CLEANUP_THREAD_LIMIT}} controls the initial number of permits of a [Semaphore|https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/Semaphore.html]. 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}} 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 h3. 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…. {code} 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 {code} |
Description |
Original:
The system property {{jenkins.branch.WorkspaceLocatorImpl$Deleter.CLEANUP_THREAD_LIMIT}} controls the initial number of permits of a [Semaphore|https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/Semaphore.html]. 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}} 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 h3. 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…. {code} 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 {code} |
New:
The system property {{jenkins.branch.WorkspaceLocatorImpl$Deleter.CLEANUP_THREAD_LIMIT}} controls the initial number of permits of a [Semaphore|https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/Semaphore.html]. 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}} 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 h3. 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…. {code} 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 {code} |
Description |
Original:
The system property {{jenkins.branch.WorkspaceLocatorImpl$Deleter.CLEANUP_THREAD_LIMIT}} controls the initial number of permits of a [Semaphore|https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/Semaphore.html]. 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}} 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 h3. 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…. {code} 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 {code} |
New:
The system property {{jenkins.branch.WorkspaceLocatorImpl$Deleter.CLEANUP_THREAD_LIMIT}} controls the initial number of permits of a [Semaphore|https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/Semaphore.html]. 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 h3. 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…. {code} 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 {code} |
Description |
Original:
The system property {{jenkins.branch.WorkspaceLocatorImpl$Deleter.CLEANUP_THREAD_LIMIT}} controls the initial number of permits of a [Semaphore|https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/Semaphore.html]. 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 h3. 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…. {code} 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 {code} |
New:
The system property {{jenkins.branch.WorkspaceLocatorImpl$Deleter.CLEANUP_THREAD_LIMIT}} controls the initial number of permits of a [Semaphore|https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/Semaphore.html]. 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. h3. 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…. {code} 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 {code} |
Description |
Original:
The system property {{jenkins.branch.WorkspaceLocatorImpl$Deleter.CLEANUP_THREAD_LIMIT}} controls the initial number of permits of a [Semaphore|https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/Semaphore.html]. 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. h3. 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…. {code} 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 {code} |
New:
The system property {{jenkins.branch.WorkspaceLocatorImpl$Deleter.CLEANUP_THREAD_LIMIT}} controls the initial number of permits of a [Semaphore|https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/Semaphore.html]. 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. h3. 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}} h3. 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…. {code} 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 {code} |
Remote Link | New: This issue links to "branch-api-plugin #495 (Web Link)" [ 30310 ] |
+1 - We have been dealing with this exact issue for some time as well and critically need it resolved