View Source

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.
# 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.