Do not take application lock(s) after unallocated lock
@@ -659,18 +659,19 @@ public class Nodes {
boolean wantToRetire = op.needsRetirement();
List<Node> result = new ArrayList<>();
try (NodeMutex lock = nodeMutex.get(); Mutex allocationLock = lockUnallocated()) {
- // This takes allocationLock to prevent any further allocation of nodes on this host
- host = lock.node();
+ // Modify parent with wantToRetire while holding the allocationLock to prevent
+ // any further allocation of nodes on this host
+ Node newHost = lock.node().withWantToRetire(wantToRetire, wantToDeprovision, wantToRebuild, agent, instant);
+ result.add(write(newHost, lock));
+ }
+
if (wantToRetire) { // Apply recursively if we're retiring
- List<Node> updatedNodes = performOn(list(allocationLock).childrenOf(host), (node, nodeLock) -> {
+ List<Node> updatedNodes = performOn(list().childrenOf(host), (node, nodeLock) -> {
Node newNode = node.withWantToRetire(wantToRetire, wantToDeprovision, wantToRebuild, agent, instant);
return write(newNode, nodeLock);
});
result.addAll(updatedNodes);
}
- Node newHost = host.withWantToRetire(wantToRetire, wantToDeprovision, wantToRebuild, agent, instant);
- result.add(write(newHost, lock));
- }
return result;
}
