Search in sources :

Example 21 with SingularityPendingTask

use of com.hubspot.singularity.SingularityPendingTask in project Singularity by HubSpot.

the class TaskRequestManager method getTaskRequests.

public List<SingularityTaskRequest> getTaskRequests(List<SingularityPendingTask> tasks) {
    final Multimap<String, SingularityPendingTask> requestIdToPendingTaskId = ArrayListMultimap.create(tasks.size(), 1);
    for (SingularityPendingTask task : tasks) {
        requestIdToPendingTaskId.put(task.getPendingTaskId().getRequestId(), task);
    }
    final List<SingularityRequestWithState> matchingRequests = requestManager.getRequests(requestIdToPendingTaskId.keySet());
    final Map<SingularityPendingTask, SingularityDeployKey> deployKeys = SingularityDeployKey.fromPendingTasks(requestIdToPendingTaskId.values());
    final Map<SingularityDeployKey, SingularityDeploy> matchingDeploys = deployManager.getDeploysForKeys(Sets.newHashSet(deployKeys.values()));
    final List<SingularityTaskRequest> taskRequests = Lists.newArrayListWithCapacity(matchingRequests.size());
    for (SingularityRequestWithState request : matchingRequests) {
        Optional<SingularityPendingDeploy> maybePendingDeploy = deployManager.getPendingDeploy(request.getRequest().getId());
        for (SingularityPendingTask task : requestIdToPendingTaskId.get(request.getRequest().getId())) {
            SingularityDeploy foundDeploy = matchingDeploys.get(deployKeys.get(task));
            if (foundDeploy == null) {
                LOG.warn("Couldn't find a matching deploy for pending task {}", task);
                continue;
            }
            if (!request.getState().isRunnable()) {
                LOG.warn("Request was in state {} for pending task {}", request.getState(), task);
                continue;
            }
            Optional<SingularityRequest> updatedRequest = maybePendingDeploy.isPresent() && maybePendingDeploy.get().getDeployMarker().getDeployId().equals(task.getPendingTaskId().getDeployId()) ? maybePendingDeploy.get().getUpdatedRequest() : Optional.<SingularityRequest>absent();
            taskRequests.add(new SingularityTaskRequest(updatedRequest.or(request.getRequest()), foundDeploy, task));
        }
    }
    return taskRequests;
}
Also used : SingularityRequest(com.hubspot.singularity.SingularityRequest) SingularityDeploy(com.hubspot.singularity.SingularityDeploy) SingularityDeployKey(com.hubspot.singularity.SingularityDeployKey) SingularityPendingTask(com.hubspot.singularity.SingularityPendingTask) SingularityPendingDeploy(com.hubspot.singularity.SingularityPendingDeploy) SingularityRequestWithState(com.hubspot.singularity.SingularityRequestWithState) SingularityTaskRequest(com.hubspot.singularity.SingularityTaskRequest)

Example 22 with SingularityPendingTask

use of com.hubspot.singularity.SingularityPendingTask in project Singularity by HubSpot.

the class SingularitySlaveAndRackManager method doesOfferMatch.

SlaveMatchState doesOfferMatch(SingularityOfferHolder offerHolder, SingularityTaskRequest taskRequest, List<SingularityTaskId> activeTaskIdsForRequest) {
    final String host = offerHolder.getHostname();
    final String rackId = offerHolder.getRackId();
    final String slaveId = offerHolder.getSlaveId();
    final MachineState currentSlaveState = slaveManager.getSlave(slaveId).get().getCurrentState().getState();
    if (currentSlaveState == MachineState.FROZEN) {
        return SlaveMatchState.SLAVE_FROZEN;
    }
    if (currentSlaveState.isDecommissioning()) {
        return SlaveMatchState.SLAVE_DECOMMISSIONING;
    }
    final MachineState currentRackState = rackManager.getRack(rackId).get().getCurrentState().getState();
    if (currentRackState == MachineState.FROZEN) {
        return SlaveMatchState.RACK_FROZEN;
    }
    if (currentRackState.isDecommissioning()) {
        return SlaveMatchState.RACK_DECOMMISSIONING;
    }
    if (!taskRequest.getRequest().getRackAffinity().or(Collections.emptyList()).isEmpty()) {
        if (!taskRequest.getRequest().getRackAffinity().get().contains(rackId)) {
            LOG.trace("Task {} requires a rack in {} (current rack {})", taskRequest.getPendingTask().getPendingTaskId(), taskRequest.getRequest().getRackAffinity().get(), rackId);
            return SlaveMatchState.RACK_AFFINITY_NOT_MATCHING;
        }
    }
    if (!isSlaveAttributesMatch(offerHolder, taskRequest)) {
        return SlaveMatchState.SLAVE_ATTRIBUTES_DO_NOT_MATCH;
    }
    final SlavePlacement slavePlacement = taskRequest.getRequest().getSlavePlacement().or(configuration.getDefaultSlavePlacement());
    if (!taskRequest.getRequest().isRackSensitive() && slavePlacement == SlavePlacement.GREEDY) {
        // todo: account for this or let this behavior continue?
        return SlaveMatchState.NOT_RACK_OR_SLAVE_PARTICULAR;
    }
    final int numDesiredInstances = taskRequest.getRequest().getInstancesSafe();
    boolean allowBounceToSameHost = isAllowBounceToSameHost(taskRequest.getRequest());
    Multiset<String> countPerRack = HashMultiset.create(slaveManager.getNumActive());
    double numOnSlave = 0;
    double numCleaningOnSlave = 0;
    double numFromSameBounceOnSlave = 0;
    double numOtherDeploysOnSlave = 0;
    boolean taskLaunchedFromBounceWithActionId = taskRequest.getPendingTask().getPendingTaskId().getPendingType() == PendingType.BOUNCE && taskRequest.getPendingTask().getActionId().isPresent();
    final String sanitizedHost = offerHolder.getSanitizedHost();
    final String sanitizedRackId = offerHolder.getSanitizedRackId();
    Collection<SingularityTaskId> cleaningTasks = leaderCache.getCleanupTaskIds();
    for (SingularityTaskId taskId : activeTaskIdsForRequest) {
        if (!cleaningTasks.contains(taskId) && taskRequest.getDeploy().getId().equals(taskId.getDeployId())) {
            countPerRack.add(taskId.getSanitizedRackId());
        }
        if (!taskId.getSanitizedHost().equals(sanitizedHost)) {
            continue;
        }
        if (taskRequest.getDeploy().getId().equals(taskId.getDeployId())) {
            if (cleaningTasks.contains(taskId)) {
                numCleaningOnSlave++;
            } else {
                numOnSlave++;
            }
            if (taskLaunchedFromBounceWithActionId) {
                Optional<SingularityTask> maybeTask = taskManager.getTask(taskId);
                boolean errorInTaskData = false;
                if (maybeTask.isPresent()) {
                    SingularityPendingTask pendingTask = maybeTask.get().getTaskRequest().getPendingTask();
                    if (pendingTask.getPendingTaskId().getPendingType() == PendingType.BOUNCE) {
                        if (pendingTask.getActionId().isPresent()) {
                            if (pendingTask.getActionId().get().equals(taskRequest.getPendingTask().getActionId().get())) {
                                numFromSameBounceOnSlave++;
                            }
                        } else {
                            // No actionId present on bounce, fall back to more restrictive placement strategy
                            errorInTaskData = true;
                        }
                    }
                } else {
                    // Could not find appropriate task data, fall back to more restrictive placement strategy
                    errorInTaskData = true;
                }
                if (errorInTaskData) {
                    allowBounceToSameHost = false;
                }
            }
        } else {
            numOtherDeploysOnSlave++;
        }
    }
    if (taskRequest.getRequest().isRackSensitive()) {
        final boolean isRackOk = isRackOk(countPerRack, sanitizedRackId, numDesiredInstances, taskRequest.getRequest().getId(), slaveId, host, numCleaningOnSlave, leaderCache);
        if (!isRackOk) {
            return SlaveMatchState.RACK_SATURATED;
        }
    }
    switch(slavePlacement) {
        case SEPARATE:
        case SEPARATE_BY_DEPLOY:
        case SPREAD_ALL_SLAVES:
            if (allowBounceToSameHost && taskLaunchedFromBounceWithActionId) {
                if (numFromSameBounceOnSlave > 0) {
                    LOG.trace("Rejecting SEPARATE task {} from slave {} ({}) due to numFromSameBounceOnSlave {}", taskRequest.getRequest().getId(), slaveId, host, numFromSameBounceOnSlave);
                    return SlaveMatchState.SLAVE_SATURATED;
                }
            } else {
                if (numOnSlave > 0 || numCleaningOnSlave > 0) {
                    LOG.trace("Rejecting {} task {} from slave {} ({}) due to numOnSlave {} numCleaningOnSlave {}", slavePlacement.name(), taskRequest.getRequest().getId(), slaveId, host, numOnSlave, numCleaningOnSlave);
                    return SlaveMatchState.SLAVE_SATURATED;
                }
            }
            break;
        case SEPARATE_BY_REQUEST:
            if (numOnSlave > 0 || numCleaningOnSlave > 0 || numOtherDeploysOnSlave > 0) {
                LOG.trace("Rejecting SEPARATE_BY_REQUEST task {} from slave {} ({}) due to numOnSlave {} numCleaningOnSlave {} numOtherDeploysOnSlave {}", taskRequest.getRequest().getId(), slaveId, host, numOnSlave, numCleaningOnSlave, numOtherDeploysOnSlave);
                return SlaveMatchState.SLAVE_SATURATED;
            }
            break;
        case OPTIMISTIC:
            // If no tasks are active for this request yet, we can fall back to greedy.
            if (activeTaskIdsForRequest.size() > 0) {
                Collection<SingularityPendingTaskId> pendingTasksForRequestClusterwide = leaderCache.getPendingTaskIdsForRequest(taskRequest.getRequest().getId());
                Set<String> currentHostsForRequest = activeTaskIdsForRequest.stream().map(SingularityTaskId::getSanitizedHost).collect(Collectors.toSet());
                final double numPerSlave = activeTaskIdsForRequest.size() / (double) currentHostsForRequest.size();
                final double leniencyCoefficient = configuration.getPlacementLeniency();
                final double threshold = numPerSlave * (1 + (pendingTasksForRequestClusterwide.size() * leniencyCoefficient));
                final boolean isSlaveOk = numOnSlave <= threshold;
                if (!isSlaveOk) {
                    LOG.trace("Rejecting OPTIMISTIC task {} from slave {} ({}) because numOnSlave {} violates threshold {} (based on active tasks for request {}, current hosts for request {}, pending tasks for request {})", taskRequest.getRequest().getId(), slaveId, host, numOnSlave, threshold, activeTaskIdsForRequest.size(), currentHostsForRequest.size(), pendingTasksForRequestClusterwide.size());
                    return SlaveMatchState.SLAVE_SATURATED;
                }
            }
            break;
        case GREEDY:
    }
    return SlaveMatchState.OK;
}
Also used : SingularityPendingTaskId(com.hubspot.singularity.SingularityPendingTaskId) SingularityTask(com.hubspot.singularity.SingularityTask) SingularityPendingTask(com.hubspot.singularity.SingularityPendingTask) SlavePlacement(com.hubspot.singularity.SlavePlacement) SingularityTaskId(com.hubspot.singularity.SingularityTaskId) MachineState(com.hubspot.singularity.MachineState)

Aggregations

SingularityPendingTask (com.hubspot.singularity.SingularityPendingTask)22 SingularityPendingTaskId (com.hubspot.singularity.SingularityPendingTaskId)9 Test (org.junit.Test)8 SingularityTask (com.hubspot.singularity.SingularityTask)6 SingularityTaskId (com.hubspot.singularity.SingularityTaskId)6 SingularityTaskRequest (com.hubspot.singularity.SingularityTaskRequest)6 SingularityPendingRequest (com.hubspot.singularity.SingularityPendingRequest)4 SingularityPendingTaskBuilder (com.hubspot.singularity.SingularityPendingTaskBuilder)4 SingularityRequest (com.hubspot.singularity.SingularityRequest)4 SingularityRequestWithState (com.hubspot.singularity.SingularityRequestWithState)4 Resources (com.hubspot.mesos.Resources)3 SingularityDeploy (com.hubspot.singularity.SingularityDeploy)3 SingularityRequestBuilder (com.hubspot.singularity.SingularityRequestBuilder)3 Timed (com.codahale.metrics.annotation.Timed)2 MachineState (com.hubspot.singularity.MachineState)2 SingularityDeployKey (com.hubspot.singularity.SingularityDeployKey)2 SingularityPendingDeploy (com.hubspot.singularity.SingularityPendingDeploy)2 SingularityRunNowRequestBuilder (com.hubspot.singularity.SingularityRunNowRequestBuilder)2 SingularityRunNowRequest (com.hubspot.singularity.api.SingularityRunNowRequest)2 TaskInfo (org.apache.mesos.v1.Protos.TaskInfo)2