use of org.apache.mesos.v1.scheduler.Protos.Call.Reconcile.Task in project Singularity by HubSpot.
the class SingularitySchedulerTest method testRecoveredTaskIsRecoveredIfLoadBalancerRemoveIsStarted.
@Test
public void testRecoveredTaskIsRecoveredIfLoadBalancerRemoveIsStarted() {
// set up the agent first
sms.resourceOffers(Arrays.asList(createOffer(1, 129, 1025, "agent1", "host1", Optional.of("rack1")))).join();
initLoadBalancedRequest();
initLoadBalancedDeploy();
SingularityTask task = launchTask(request, firstDeploy, 1, TaskState.TASK_RUNNING);
Assertions.assertEquals(1, taskManager.getNumActiveTasks());
TaskStatus lost = TaskStatus.newBuilder().setTaskId(MesosProtosUtils.toTaskId(task.getMesosTask().getTaskId())).setAgentId(MesosProtosUtils.toAgentId(task.getAgentId())).setReason(Reason.REASON_AGENT_REMOVED).setMessage("health check timed out").setState(TaskState.TASK_LOST).build();
sms.statusUpdate(lost).join();
Assertions.assertEquals(0, taskManager.getNumActiveTasks());
SingularityTaskId taskId = task.getTaskId();
Assertions.assertTrue(taskManager.getTaskHistory(taskId).isPresent());
taskManager.saveLoadBalancerState(taskId, LoadBalancerRequestType.REMOVE, new SingularityLoadBalancerUpdate(LoadBalancerRequestState.UNKNOWN, new LoadBalancerRequestId(taskId.getId(), LoadBalancerRequestType.REMOVE, Optional.<Integer>empty()), Optional.empty(), System.currentTimeMillis(), LoadBalancerMethod.DELETE, Optional.empty()));
TaskStatus recovered = TaskStatus.newBuilder().setTaskId(MesosProtosUtils.toTaskId(task.getMesosTask().getTaskId())).setAgentId(MesosProtosUtils.toAgentId(task.getAgentId())).setReason(Reason.REASON_AGENT_REREGISTERED).setMessage("agent reregistered").setState(TaskState.TASK_RUNNING).build();
sms.statusUpdate(recovered).join();
newTaskChecker.getTaskCheckFutures().forEach(f -> {
try {
f.get(5, TimeUnit.SECONDS);
} catch (TimeoutException te) {
// Didn't see that....
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
});
Assertions.assertEquals(1, taskManager.getNumActiveTasks());
Assertions.assertEquals(0, taskManager.getNumCleanupTasks());
Assertions.assertEquals(1, requestManager.getSizeOfPendingQueue());
Assertions.assertTrue(taskManager.getLoadBalancerState(taskId, LoadBalancerRequestType.ADD).isPresent());
}
use of org.apache.mesos.v1.scheduler.Protos.Call.Reconcile.Task in project Singularity by HubSpot.
the class SingularitySchedulerTestBase method prepTask.
protected SingularityTask prepTask(SingularityRequest request, SingularityDeploy deploy, long launchTime, int instanceNo, boolean separateHosts, Optional<String> runId, Optional<String> agentAndRack) {
SingularityPendingTask pendingTask = buildPendingTask(request, deploy, launchTime, instanceNo, runId);
SingularityTaskRequest taskRequest = new SingularityTaskRequest(request, deploy, pendingTask);
Offer offer;
if (separateHosts || agentAndRack.isPresent()) {
offer = createOffer(125, 1024, 2048, agentAndRack.orElse(String.format("agent%s", instanceNo)), agentAndRack.orElse(String.format("host%s", instanceNo)), agentAndRack);
} else {
offer = createOffer(125, 1024, 2048);
}
SingularityTaskId taskId = new SingularityTaskId(request.getId(), deploy.getId(), launchTime, instanceNo, offer.getHostname(), agentAndRack.orElse("rack1"));
TaskID taskIdProto = TaskID.newBuilder().setValue(taskId.toString()).build();
TaskInfo taskInfo = TaskInfo.newBuilder().setAgentId(offer.getAgentId()).setExecutor(ExecutorInfo.newBuilder().setExecutorId(ExecutorID.newBuilder().setValue("executorID"))).setTaskId(taskIdProto).setName("name").build();
SingularityTask task = new SingularityTask(taskRequest, taskId, Collections.singletonList(mesosProtosUtils.offerFromProtos(offer)), mesosProtosUtils.taskFromProtos(taskInfo), Optional.of("rack1"));
taskManager.savePendingTask(pendingTask);
return task;
}
use of org.apache.mesos.v1.scheduler.Protos.Call.Reconcile.Task in project Singularity by HubSpot.
the class SingularityMesosTaskBuilder method prepareCustomExecutor.
/**
* Prepares the Mesos TaskInfo object when using our custom SingularityExecutor.
*/
private void prepareCustomExecutor(final TaskInfo.Builder bldr, final SingularityTaskId taskId, final SingularityTaskRequest task, final SingularityOfferHolder offerHolder, final Optional<long[]> ports, final Resources desiredExecutorResources) {
CommandInfo.Builder commandBuilder = CommandInfo.newBuilder().setValue(task.getDeploy().getCustomExecutorCmd().get());
prepareEnvironment(task, taskId, commandBuilder, offerHolder, ports);
if (task.getDeploy().getUser().isPresent()) {
commandBuilder.setUser(task.getDeploy().getUser().get());
}
prepareMesosUriDownloads(task.getPendingTask().getExtraArtifacts(), commandBuilder);
bldr.setExecutor(ExecutorInfo.newBuilder().setCommand(commandBuilder.build()).setExecutorId(ExecutorID.newBuilder().setValue(task.getDeploy().getCustomExecutorId().orElse(idGenerator.getNextExecutorId()))).setSource(// set source to taskId for use in statistics endpoint, TODO: remove
task.getDeploy().getCustomExecutorSource().orElse(taskId.getId())).setLabels(Labels.newBuilder().addLabels(Label.newBuilder().setKey("taskId").setValue(taskId.getId()))).addAllResources(buildMesosResources(desiredExecutorResources, task.getRequest().getRequiredRole())).build());
if (task.getDeploy().getExecutorData().isPresent()) {
final ExecutorDataBuilder executorDataBldr = task.getDeploy().getExecutorData().get().toBuilder();
String defaultS3Bucket = "";
String s3UploaderKeyPattern = "";
if (configuration.getS3ConfigurationOptional().isPresent()) {
if (task.getRequest().getGroup().isPresent() && configuration.getS3ConfigurationOptional().get().getGroupOverrides().containsKey(task.getRequest().getGroup().get())) {
defaultS3Bucket = configuration.getS3ConfigurationOptional().get().getGroupOverrides().get(task.getRequest().getGroup().get()).getS3Bucket();
LOG.trace("Setting defaultS3Bucket to {} for task {} executorData", defaultS3Bucket, taskId.getId());
} else {
defaultS3Bucket = configuration.getS3ConfigurationOptional().get().getS3Bucket();
}
s3UploaderKeyPattern = configuration.getS3ConfigurationOptional().get().getS3KeyFormat();
}
if (task.getPendingTask().getCmdLineArgsList().isPresent() && !task.getPendingTask().getCmdLineArgsList().get().isEmpty()) {
LOG.trace("Adding cmd line args {} to task {} executorData", task.getPendingTask().getCmdLineArgsList(), taskId.getId());
final ImmutableList.Builder<String> extraCmdLineArgsBuilder = ImmutableList.builder();
if (executorDataBldr.getExtraCmdLineArgs() != null && !executorDataBldr.getExtraCmdLineArgs().isEmpty()) {
extraCmdLineArgsBuilder.addAll(executorDataBldr.getExtraCmdLineArgs());
}
extraCmdLineArgsBuilder.addAll(task.getPendingTask().getCmdLineArgsList().get());
executorDataBldr.setExtraCmdLineArgs(extraCmdLineArgsBuilder.build());
}
List<SingularityS3UploaderFile> uploaderAdditionalFiles = new ArrayList<>();
if (configuration.getS3ConfigurationOptional().isPresent()) {
uploaderAdditionalFiles.addAll(configuration.getS3ConfigurationOptional().get().getS3UploaderAdditionalFiles());
}
uploaderAdditionalFiles.addAll(task.getPendingTask().getS3UploaderAdditionalFiles());
uploaderAdditionalFiles.addAll(task.getDeploy().getS3UploaderAdditionalFiles());
Optional<String> maybeS3StorageClass = configuration.getS3ConfigurationOptional().isPresent() ? configuration.getS3ConfigurationOptional().get().getS3StorageClass() : Optional.<String>empty();
Optional<Long> maybeApplyAfterBytes = configuration.getS3ConfigurationOptional().isPresent() ? configuration.getS3ConfigurationOptional().get().getApplyS3StorageClassAfterBytes() : Optional.<Long>empty();
if (task.getPendingTask().getRunAsUserOverride().isPresent()) {
executorDataBldr.setUser(task.getPendingTask().getRunAsUserOverride());
}
Optional<HealthcheckOptions> healthcheckOptions = task.getRequest().getSkipHealthchecks().orElse(false) ? Optional.empty() : task.getDeploy().getHealthcheck();
final SingularityTaskExecutorData executorData = new SingularityTaskExecutorData(executorDataBldr.build(), uploaderAdditionalFiles, defaultS3Bucket, s3UploaderKeyPattern, configuration.getCustomExecutorConfiguration().getServiceLog(), configuration.getCustomExecutorConfiguration().getServiceFinishedTailLog(), task.getRequest().getGroup(), maybeS3StorageClass, maybeApplyAfterBytes, getCpuHardLimit(task), healthcheckOptions);
try {
bldr.setData(ByteString.copyFromUtf8(objectMapper.writeValueAsString(executorData)));
} catch (JsonProcessingException e) {
LOG.warn("Unable to process executor data {} for task {} as json (trying as string)", executorData, taskId.getId(), e);
bldr.setData(ByteString.copyFromUtf8(executorData.toString()));
}
} else if (task.getDeploy().getCommand().isPresent()) {
bldr.setData(ByteString.copyFromUtf8(task.getDeploy().getCommand().get()));
}
}
use of org.apache.mesos.v1.scheduler.Protos.Call.Reconcile.Task in project Singularity by HubSpot.
the class SingularityOfferHolder method launchTasksAndGetUnusedOffers.
public List<Offer> launchTasksAndGetUnusedOffers(SingularityMesosSchedulerClient schedulerClient) {
final List<TaskInfo> toLaunch = Lists.newArrayListWithCapacity(acceptedTasks.size());
final List<SingularityTaskId> taskIds = Lists.newArrayListWithCapacity(acceptedTasks.size());
for (SingularityMesosTaskHolder taskHolder : acceptedTasks) {
taskIds.add(taskHolder.getTask().getTaskId());
toLaunch.add(taskHolder.getMesosTask());
LOG.debug("Launching {} with possible offers {}", taskHolder.getTask().getTaskId(), MesosUtils.formatOfferIdsForLog(offers));
LOG.trace("Launching {} mesos task: {}", taskHolder.getTask().getTaskId(), MesosUtils.formatForLogging(taskHolder.getMesosTask()));
}
// At this point, `currentResources` contains a list of unused resources, because we subtracted out the required resources of every task we accepted.
// Let's try and reclaim offers by trying to pull each offer's list of resources out of the combined pool of leftover resources.
// n.b., This is currently not optimal. We just look through the offers in this instance and try to reclaim them with no particular priority or order.
Map<Boolean, List<Offer>> partitionedOffers = offers.stream().collect(Collectors.partitioningBy(offer -> {
List<Long> ports = MesosUtils.getAllPorts(offer.getResourcesList());
boolean offerCanBeReclaimedFromUnusedResources = offer.getResourcesList().stream().collect(Collectors.groupingBy(Resource::getRole)).entrySet().stream().map(entry -> {
// Now, for each set of offer Resources grouped by role...
String role = entry.getKey();
List<Resource> offerResources = entry.getValue();
Optional<String> maybeRole = (!role.equals("") && !role.equals("*")) ? Optional.of(role) : Optional.empty();
// ...Check if we can pull the Resources belonging to this offer out of the pool of `currentResources`.
return MesosUtils.doesOfferMatchResources(maybeRole, MesosUtils.buildResourcesFromMesosResourceList(offerResources, maybeRole), currentResources, ports);
}).reduce(true, (x, y) -> x && y);
if (offerCanBeReclaimedFromUnusedResources) {
// We can reclaim this offer in its entirety! Pull all of its resources out of the combined pool for this SingularityOfferHolder instance.
LOG.trace("Able to reclaim offer {} from unused resources in OfferHolder from host {}. cpu: {}, mem: {}, disk: {}", offer.getId().getValue(), offer.getHostname(), MesosUtils.getNumCpus(offer), MesosUtils.getMemory(offer), MesosUtils.getDisk(offer));
currentResources = MesosUtils.subtractResources(currentResources, offer.getResourcesList());
}
return offerCanBeReclaimedFromUnusedResources;
}));
List<Offer> leftoverOffers = partitionedOffers.get(true);
List<Offer> neededOffers = partitionedOffers.get(false);
schedulerClient.accept(neededOffers.stream().map(Offer::getId).collect(Collectors.toList()), Collections.singletonList(Operation.newBuilder().setType(Type.LAUNCH).setLaunch(Launch.newBuilder().addAllTaskInfos(toLaunch).build()).build()));
LOG.debug("Launched tasks with offers {}, unused: {}", MesosUtils.formatOfferIdsForLog(neededOffers), MesosUtils.formatOfferIdsForLog(leftoverOffers));
LOG.info("{} tasks ({}) launched", taskIds.size(), taskIds);
return leftoverOffers;
}
use of org.apache.mesos.v1.scheduler.Protos.Call.Reconcile.Task in project Singularity by HubSpot.
the class SingularityTaskSizeOptimizer method getSizeOptimizedTask.
SingularityTask getSizeOptimizedTask(SingularityMesosTaskHolder taskHolder) {
if (configuration.isStoreAllMesosTaskInfoForDebugging()) {
return taskHolder.getTask();
}
SingularityTask task = taskHolder.getTask();
TaskInfo.Builder mesosTask = taskHolder.getMesosTask().toBuilder();
mesosTask.clearData();
List<MesosOfferObject> offers = task.getOffers().stream().map(MesosOfferObject::sizeOptimized).collect(Collectors.toList());
SingularityTaskRequest taskRequest = task.getTaskRequest();
if (task.getTaskRequest().getDeploy().getExecutorData().isPresent()) {
SingularityDeployBuilder deploy = task.getTaskRequest().getDeploy().toBuilder();
deploy.setExecutorData(Optional.empty());
taskRequest = new SingularityTaskRequest(task.getTaskRequest().getRequest(), deploy.build(), task.getTaskRequest().getPendingTask());
}
return new SingularityTask(taskRequest, task.getTaskId(), offers, mesosProtosUtils.taskFromProtos(mesosTask.build()), task.getRackId());
}
Aggregations