Search in sources :

Example 1 with Mutex

use of com.yahoo.transaction.Mutex in project vespa by vespa-engine.

the class NodeRepository method removeRecursively.

private List<Node> removeRecursively(Node node, boolean force) {
    try (Mutex lock = lockUnallocated()) {
        List<Node> removed = !node.type().isDockerHost() ? new ArrayList<>() : getChildNodes(node.hostname()).stream().filter(child -> force || verifyRemovalIsAllowed(child, true)).collect(Collectors.toList());
        if (force || verifyRemovalIsAllowed(node, false))
            removed.add(node);
        db.removeNodes(removed);
        return removed;
    } catch (RuntimeException e) {
        throw new IllegalArgumentException("Failed to delete " + node.hostname(), e);
    }
}
Also used : Mutex(com.yahoo.transaction.Mutex)

Example 2 with Mutex

use of com.yahoo.transaction.Mutex in project vespa by vespa-engine.

the class ApplicationMaintainer method deployWithLock.

/**
 * Redeploy this application. A lock will be taken for the duration of the deployment activation
 */
final void deployWithLock(ApplicationId application) {
    // Lock is acquired with a low timeout to reduce the chance of colliding with an external deployment.
    try (Mutex lock = nodeRepository().lock(application, Duration.ofSeconds(1))) {
        // became inactive since deployment was requested
        if (!isActive(application))
            return;
        Optional<Deployment> deployment = deployer.deployFromLocalActive(application);
        // this will be done at another config server
        if (!deployment.isPresent())
            return;
        deployment.get().activate();
    } catch (RuntimeException e) {
        log.log(Level.WARNING, "Exception on maintenance redeploy", e);
    }
}
Also used : Deployment(com.yahoo.config.provision.Deployment) Mutex(com.yahoo.transaction.Mutex)

Example 3 with Mutex

use of com.yahoo.transaction.Mutex in project vespa by vespa-engine.

the class NodeFailer method maintain.

@Override
protected void maintain() {
    // Ready nodes
    try (Mutex lock = nodeRepository().lockUnallocated()) {
        updateNodeLivenessEventsForReadyNodes();
        getReadyNodesByFailureReason().forEach((node, reason) -> {
            if (!throttle(node)) {
                nodeRepository().fail(node.hostname(), Agent.system, reason);
            }
        });
    }
    // Active nodes
    for (Node node : determineActiveNodeDownStatus()) {
        Instant graceTimeEnd = node.history().event(History.Event.Type.down).get().at().plus(downTimeLimit);
        if (graceTimeEnd.isBefore(clock.instant()) && !applicationSuspended(node) && failAllowedFor(node.type()))
            if (!throttle(node))
                failActive(node, "Node has been down longer than " + downTimeLimit);
    }
}
Also used : Node(com.yahoo.vespa.hosted.provision.Node) Instant(java.time.Instant) Mutex(com.yahoo.transaction.Mutex)

Example 4 with Mutex

use of com.yahoo.transaction.Mutex in project vespa by vespa-engine.

the class NodeRetirer method retireUnallocated.

/**
 * Retires unallocated nodes by moving them directly to parked.
 * Returns true iff all there are no unallocated nodes that match the retirement policy
 */
boolean retireUnallocated() {
    try (Mutex lock = nodeRepository().lockUnallocated()) {
        List<Node> allNodes = nodeRepository().getNodes(NodeType.tenant);
        Map<Flavor, Map<Node.State, Long>> numSpareNodesByFlavorByState = getNumberOfNodesByFlavorByNodeState(allNodes);
        flavorSpareChecker.updateReadyAndActiveCountsByFlavor(numSpareNodesByFlavorByState);
        long numFlavorsWithUnsuccessfullyRetiredNodes = allNodes.stream().filter(node -> node.state() == Node.State.ready).filter(node -> retirementPolicy.shouldRetire(node).isPresent()).collect(Collectors.groupingBy(Node::flavor, Collectors.toSet())).entrySet().stream().filter(entry -> {
            Set<Node> nodesThatShouldBeRetiredForFlavor = entry.getValue();
            for (Iterator<Node> iter = nodesThatShouldBeRetiredForFlavor.iterator(); iter.hasNext(); ) {
                Node nodeToRetire = iter.next();
                if (!flavorSpareChecker.canRetireUnallocatedNodeWithFlavor(nodeToRetire.flavor()))
                    break;
                retirementPolicy.shouldRetire(nodeToRetire).ifPresent(reason -> {
                    nodeRepository().write(nodeToRetire.with(nodeToRetire.status().withWantToDeprovision(true)));
                    nodeRepository().park(nodeToRetire.hostname(), Agent.NodeRetirer, reason);
                    iter.remove();
                });
            }
            if (!nodesThatShouldBeRetiredForFlavor.isEmpty()) {
                String commaSeparatedHostnames = nodesThatShouldBeRetiredForFlavor.stream().map(Node::hostname).collect(Collectors.joining(", "));
                log.info(String.format("Failed to retire %s, wanted to retire %d nodes (%s), but there are no spare nodes left.", entry.getKey(), nodesThatShouldBeRetiredForFlavor.size(), commaSeparatedHostnames));
            }
            return !nodesThatShouldBeRetiredForFlavor.isEmpty();
        }).count();
        return numFlavorsWithUnsuccessfullyRetiredNodes == 0;
    }
}
Also used : Deployer(com.yahoo.config.provision.Deployer) FlavorSpareChecker(com.yahoo.vespa.hosted.provision.provisioning.FlavorSpareChecker) RetirementPolicy(com.yahoo.vespa.hosted.provision.maintenance.retire.RetirementPolicy) Iterator(java.util.Iterator) ApplicationId(com.yahoo.config.provision.ApplicationId) Deployment(com.yahoo.config.provision.Deployment) NodeType(com.yahoo.config.provision.NodeType) Collection(java.util.Collection) ClusterSpec(com.yahoo.config.provision.ClusterSpec) Set(java.util.Set) HashMap(java.util.HashMap) Node(com.yahoo.vespa.hosted.provision.Node) Logger(java.util.logging.Logger) Collectors(java.util.stream.Collectors) NodeRepository(com.yahoo.vespa.hosted.provision.NodeRepository) Mutex(com.yahoo.transaction.Mutex) List(java.util.List) Stream(java.util.stream.Stream) Agent(com.yahoo.vespa.hosted.provision.node.Agent) Flavor(com.yahoo.config.provision.Flavor) Duration(java.time.Duration) Map(java.util.Map) LogLevel(com.yahoo.log.LogLevel) Optional(java.util.Optional) Set(java.util.Set) Node(com.yahoo.vespa.hosted.provision.Node) Iterator(java.util.Iterator) Mutex(com.yahoo.transaction.Mutex) Flavor(com.yahoo.config.provision.Flavor) HashMap(java.util.HashMap) Map(java.util.Map)

Example 5 with Mutex

use of com.yahoo.transaction.Mutex in project vespa by vespa-engine.

the class NodeRepository method performOn.

/**
 * Performs an operation requiring locking on all nodes matching some filter.
 *
 * @param filter the filter determining the set of nodes where the operation will be performed
 * @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
 */
private List<Node> performOn(NodeFilter filter, UnaryOperator<Node> action) {
    List<Node> unallocatedNodes = new ArrayList<>();
    ListMap<ApplicationId, Node> allocatedNodes = new ListMap<>();
    // Group matching nodes by the lock needed
    for (Node node : db.getNodes()) {
        if (!filter.matches(node))
            continue;
        if (node.allocation().isPresent())
            allocatedNodes.put(node.allocation().get().owner(), node);
        else
            unallocatedNodes.add(node);
    }
    // perform operation while holding locks
    List<Node> resultingNodes = new ArrayList<>();
    try (Mutex lock = lockUnallocated()) {
        for (Node node : unallocatedNodes) resultingNodes.add(action.apply(node));
    }
    for (Map.Entry<ApplicationId, List<Node>> applicationNodes : allocatedNodes.entrySet()) {
        try (Mutex lock = lock(applicationNodes.getKey())) {
            for (Node node : applicationNodes.getValue()) resultingNodes.add(action.apply(node));
        }
    }
    return resultingNodes;
}
Also used : ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) Mutex(com.yahoo.transaction.Mutex) ApplicationId(com.yahoo.config.provision.ApplicationId) Map(java.util.Map) ListMap(com.yahoo.collections.ListMap) ListMap(com.yahoo.collections.ListMap)

Aggregations

Mutex (com.yahoo.transaction.Mutex)11 Node (com.yahoo.vespa.hosted.provision.Node)5 ApplicationId (com.yahoo.config.provision.ApplicationId)4 Deployment (com.yahoo.config.provision.Deployment)4 List (java.util.List)4 Map (java.util.Map)4 Flavor (com.yahoo.config.provision.Flavor)3 NodeType (com.yahoo.config.provision.NodeType)3 Agent (com.yahoo.vespa.hosted.provision.node.Agent)3 Duration (java.time.Duration)3 ArrayList (java.util.ArrayList)3 Optional (java.util.Optional)3 Set (java.util.Set)3 Collectors (java.util.stream.Collectors)3 ListMap (com.yahoo.collections.ListMap)2 ClusterSpec (com.yahoo.config.provision.ClusterSpec)2 Deployer (com.yahoo.config.provision.Deployer)2 LogLevel (com.yahoo.log.LogLevel)2 NodeRepository (com.yahoo.vespa.hosted.provision.NodeRepository)2 RetirementPolicy (com.yahoo.vespa.hosted.provision.maintenance.retire.RetirementPolicy)2