public List<Node> performOnRecursively(NodeList parents, Predicate<RecursiveNodeMutexes> filter, Function<RecursiveNodeMutexes, List<Node>> action) {
        for (Node node : parents)
            if (node.parentHostname().isPresent())
                throw new IllegalArgumentException(node + " is not a parent host");

        List<Node> resultingNodes = new ArrayList<>();
        for (Node parent : parents) {
            try (RecursiveNodeMutexes locked = lockAndGetRecursively(parent.hostname(), Optional.empty())) {
                if (filter.test(locked))
                    resultingNodes.addAll(action.apply(locked));
            }
        }
        return resultingNodes;
    }
Performs an operation requiring locking on all given nodes.

@param action the action to perform
@return the set of nodes on which the action was performed, as they became as a result of the operation
node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Nodes.java