changes.
| h1. Situation |
| Some jobs may need to acquire particular resource non-exclusively, while some other jobs need to acquire the resource exclusively. If the resource is exclusively acquired, both exclusive jobs and non-exclusive jobs must wait. On the other hand, if the resource is non-exclusively acquired, exclusive jobs must wait, but non-exclusive jobs can continue to acquire the resource. |
| |
| h1. Demonstration |
| | Configuration [read1|http://demo.pmease.com/dashboard/80] and [read2|http://demo.pmease.com/dashboard/81] access _resource2_ on the server node non-exclusively, while configuration [write1|http://demo.pmease.com/dashboard/82] and [write2|http://demo.pmease.com/dashboard/83] access _resource2_ on the server node exclusively. |
| | Configuration [read1|http://demo.pmease.com/overview/80] and [read2|http://demo.pmease.com/overview/81] access _resource2_ on the server node non-exclusively, while configuration [write1|http://demo.pmease.com/overview/82] and [write2|http://demo.pmease.com/overview/83] access _resource2_ on the server node exclusively. |
| # Trigger read1 and read2 respectively, check their build logs, and you will find that these two configurations are printing _do my job with acquired resource..._ which means that the step is being executed. |
| # Trigger write1 and write2 before read configurations finish, check their build logs, and you will find that both are printing the message _Executing pre-execute script..._ which means that the step is waiting to acquire the resource. |
| # After both read1 and read2 finishes, one of the write configuration will do its job while another is still waiting. |
| # Trigger read1 and read2 again before write configurations finish, check their build logs, and you will find that both are waiting to acquire resource2. |
| |
| h1. Resolution |
| # pre-execute action of master step of read1 and read2 is defined to execute below script: |
| {code} |
| groovy: |
| node.getResource("resource2", new java.util.concurrent.locks.ReentrantReadWriteLock()).readLock().lock(); |
| {code} |
| This tells QuickBuild to get node resource named _resource2_, and associate a Java read write lock with the name if the resource does not already exist. And then acquire the non-exclusive lock by calling _readLock().lock()_ before executing the step. |
| # post-execute action of master step of read1 and read2 is defined to execute below script: |
| {code} |
| groovy: |
| node.getResource("resource2").readLock().unlock(); |
| {code} |
| This tells QuickBuild to release the non-exclusive resource before step finishes. |
| # pre-execute action of master step of write1 and write2 is defined to execute below script: |
| {code} |
| groovy: |
| node.getResource("resource2", new java.util.concurrent.locks.ReentrantReadWriteLock()).writeLock().lock(); |
| {code} |
| This tells QuickBuild to get node resource named _resource2_, and associate a Java read write lock with the name if the resource does not already exist. And then acquire the exclusive lock by calling _writeLock().lock()_ before executing the step. |
| # post-execute action of master step of write1 and write2 is defined to execute below script: |
| {code} |
| groovy: |
| node.getResource("resource2").writeLock().unlock(); |
| {code} |
| This tells QuickBuild to release the exclusive resource before step finishes. |