View Source

h1. Control Build Concurrency with Resources

As explained in [working with resources] section, one can define resources in grid page to control how many steps can run concurrently. Specifically, if resource requirement is applied to master step, the whole build will be queued when the requirement is not satisfied. You may also refer to [the resource management tutorial|resource management] on how to control the build concurrency.

h1. Concurrency of Builds of the Same Configuration

Concurrency of builds of the same configuration is also affected by workspaces. QuickBuild guarantees that a workspace is only used by one build at a time. Assume that _step1_ and _step2_ belongs to _build1_ and _build2_ respectively. If _step1_ and _step2_ both matches the single same node, the second step will wait until the first step finishes. Specifically if the waiting step is of master step, the whole build will be put into queue for waiting.

h1. Possible Deadlocks

Deadlock is possible if a child step requires a resource which has already been acquired by parent step. Taking the [One Build for One Agent] example, if the child step _test_ of [child project1|http://demo.pmease.com/settings/102/steps] also requires resource _Agent_, deadlock will happen if there is only one agent available. In this case:
# master step has already acquired resource _Agent_.
# master step will not finish unless child step _test_ starts and finishes.
# child step _test_ will not start unless it can get a free _Agent_ resource.
# resource _Agent_ will not be free unless master step finishes.

This makes the system enters into a infinite waiting loop unless there is another free _Agent_ resource is available. Considering there might be many builds running in the system concurrently, deadlock can happen regardless how many resource you configured in the system.

To avoid such deadlock is simple: never try to acquire the same resource multiple times in the same build.

Another deadlock possibility is caused by looped waiting of different resources. Assume that:
# we have two resources in the system: _resource1_ and _resource2_.
# master step of _build1_ (assume _master1_) requires _resource1_ and its child step _child1_ requires _resource2_.
# master step of _build2_ (assume _master2_) requires _resource2_ and its child step _child2_ requires _resource1_.

Deadlock may happen if there is only one _resource1_ and _resource2_ and if we run _build1_ and _build2_ at the same time:
# _master1_ acquires _resource1_.
# _master2_ acquires _resource2_.
# _master1_ will not finish unless _child1_ starts and finishes.
# _master2_ will not finish unless _child2_ starts and finishes.
# _child1_ will not start unless _resource2_ is released by _master2_.
# _child2_ will not start unless _resource1_ is released by _master1_.

Even if there are multiple _resource1_ and _resource2_ configured in the system, deadlock can still happen if many builds of this type are running together. To avoid such deadlock, you should avoid looped waiting of different resources. If _resource1_ waits for _resource2_ in a build setup, you should be careful that other build setups will never cause _resource2_ to wait for _resource1_. This also holds true if three or more resources are involved.