this.offeredTime = System.currentTimeMillis(); List<Protos.Resource> resources = new ArrayList<>(offer.getResourcesList().size()); Map<String, Double> aggregatedScalarResourceMap = new HashMap<String, Double>() { @Override for (Protos.Resource resource : offer.getResourcesList()) { switch (resource.getType()) { case SCALAR:
for (Protos.Resource resource : offer.getResourcesList()) { if (resource.getName().equals(CPU)) { if (resource.getType().equals(Protos.Value.Type.SCALAR)) log.log(Level.FINE, "Offer not sufficient for slave request: {0}", offer.getResourcesList()); log.log(Level.FINE, "Offer not sufficient for slave request: {0}", offer.getResourcesList()); return new IgniteTask(offer.getHostname(), cpus, mem, disk); else { log.log(Level.FINE, "Offer not sufficient for slave request: {0}", offer.getResourcesList());
static double scalarSum(Protos.Offer offer, String name) { return offer.getResourcesList().stream().filter(resource -> resource.getName().equals(name)).mapToDouble(resource -> resource.getScalar().getValue()).sum(); } }
double diskNeeded = request.request.diskNeeded; for (Resource r : offer.getResourcesList()) { if (r.getName().equals("cpus") && cpusNeeded > 0) { double cpus = Math.min(r.getScalar().getValue(), cpusNeeded);
@Test public void testUninstallStepsComplete() throws Exception { Protos.Offer offer = OfferTestUtils.getOffer(Arrays.asList(RESERVED_RESOURCE_1, RESERVED_RESOURCE_2)); UninstallScheduler uninstallScheduler = getUninstallScheduler(); // Invoke getClientStatus so that plan status is correctly processed before offers are passed: Assert.assertEquals(ClientStatusResponse.launching(true), uninstallScheduler.getClientStatus()); uninstallScheduler.offers(Collections.singletonList(offer)); // Verify that scheduler doesn't expect _1 and _2. It then expects that they have been cleaned: UnexpectedResourcesResponse response = uninstallScheduler.getUnexpectedResources(Collections.singletonList(offer)); Assert.assertEquals(UnexpectedResourcesResponse.Result.PROCESSED, response.result); Assert.assertEquals(1, response.offerResources.size()); Assert.assertEquals(offer.getResourcesList(), response.offerResources.iterator().next().getResources()); // Check that _1 and _2 are now marked as complete, while _3 is still prepared: Plan plan = getUninstallPlan(uninstallScheduler); List<Status> expected = Arrays.asList(Status.COMPLETE, Status.COMPLETE, Status.COMPLETE, Status.PREPARED, Status.PENDING); Assert.assertEquals(plan.toString(), expected, getStepStatuses(plan)); // Invoke getClientStatus so that plan status is correctly processed before offers are passed. // Shouldn't see any new work since all the uninstall steps were considered candidates up-front. Assert.assertEquals(ClientStatusResponse.launching(false), uninstallScheduler.getClientStatus()); offer = OfferTestUtils.getOffer(Collections.singletonList(RESERVED_RESOURCE_3)); uninstallScheduler.offers(Collections.singletonList(offer)); // Verify that scheduler doesn't expect _3. It then expects that it has been cleaned: response = uninstallScheduler.getUnexpectedResources(Collections.singletonList(offer)); Assert.assertEquals(UnexpectedResourcesResponse.Result.PROCESSED, response.result); Assert.assertEquals(1, response.offerResources.size()); Assert.assertEquals(offer.getResourcesList(), response.offerResources.iterator().next().getResources()); expected = Arrays.asList(Status.COMPLETE, Status.COMPLETE, Status.COMPLETE, Status.COMPLETE, Status.PENDING); Assert.assertEquals(expected, getStepStatuses(plan)); }
offerList.add(offer); for (Protos.Resource r : offer.getResourcesList()) { ResourceType resourceType = ResourceType.of(r.getName()); ReservationType reservationType = (r.getRole().equals("*")) ?
@VisibleForTesting SortedSet<Long> findPortsToUse(Offer offer, int maxCount) { SortedSet<Long> portsToUse = new TreeSet<Long>(); List<Value.Range> portRangesList = null; // Locate the port resource in the offer for (Resource resource : offer.getResourcesList()) { if (resource.getName().equals(PORT_RESOURCE_NAME)) { portRangesList = resource.getRanges().getRangeList(); break; } } LOGGER.fine("portRangesList=" + portRangesList); /** * We need to find maxCount ports to use. * We are provided a list of port ranges to use * We are assured by the offer check that we have enough ports to use */ // Check this port range for ports that we can use if (portRangesList != null) { for (Value.Range currentPortRange : portRangesList) { // Check each port until we reach the end of the current range long begin = currentPortRange.getBegin(); long end = currentPortRange.getEnd(); for (long candidatePort = begin; candidatePort <= end && portsToUse.size() < maxCount; candidatePort++) { portsToUse.add(candidatePort); } } } return portsToUse; }
@Test public void testPlanCompletes() throws Exception { Protos.Offer offer = OfferTestUtils.getOffer(Arrays.asList( RESERVED_RESOURCE_1, RESERVED_RESOURCE_2, RESERVED_RESOURCE_3)); UninstallScheduler uninstallScheduler = getUninstallScheduler(); // Invoke getClientStatus so that plan status is correctly processed before offers are passed: Assert.assertEquals(ClientStatusResponse.launching(true), uninstallScheduler.getClientStatus()); uninstallScheduler.offers(Collections.singletonList(offer)); // Verify that scheduler doesn't expect _1/_2/_3. It then expects that they have been cleaned: UnexpectedResourcesResponse response = uninstallScheduler.getUnexpectedResources(Collections.singletonList(offer)); Assert.assertEquals(UnexpectedResourcesResponse.Result.PROCESSED, response.result); Assert.assertEquals(1, response.offerResources.size()); Assert.assertEquals(offer.getResourcesList(), response.offerResources.iterator().next().getResources()); Plan plan = getUninstallPlan(uninstallScheduler); List<Status> expected = Arrays.asList(Status.COMPLETE, Status.COMPLETE, Status.COMPLETE, Status.COMPLETE, Status.PENDING); Assert.assertEquals(plan.toString(), expected, getStepStatuses(plan)); // Turn the crank once to prepare the deregistration Step Assert.assertEquals(ClientStatusResponse.launching(true), uninstallScheduler.getClientStatus()); uninstallScheduler.offers(Collections.singleton(getOffer())); expected = Arrays.asList(Status.COMPLETE, Status.COMPLETE, Status.COMPLETE, Status.COMPLETE, Status.PREPARED); Assert.assertEquals(plan.toString(), expected, getStepStatuses(plan)); // Advertise an UNINSTALLED state so that upstream will clean us up and call unregistered(): Assert.assertEquals(ClientStatusResponse.readyToRemove(), uninstallScheduler.getClientStatus()); // Deregistration completes only after we've told the scheduler that it's unregistered uninstallScheduler.unregistered(); expected = Arrays.asList(Status.COMPLETE, Status.COMPLETE, Status.COMPLETE, Status.COMPLETE, Status.COMPLETE); Assert.assertEquals(plan.toString(), expected, getStepStatuses(plan)); Assert.assertTrue(plan.isComplete()); }
/** * Returns the resources which are not expected by this service. When uninstalling, all resources are unexpected. * The {@link UninstallScheduler} just keeps track of them on its 'checklist' as they are removed. */ @Override public UnexpectedResourcesResponse getUnexpectedResources(Collection<Protos.Offer> unusedOffers) { Collection<OfferResources> unexpected = unusedOffers.stream() .map(offer -> new OfferResources(offer).addAll(offer.getResourcesList().stream() // Omit any unreserved resources, and any unrefined pre-reserved resources. // In addition, checking for a valid resource_id label is a good sanity check to avoid // potentially unreserving any resources that weren't originally created by the SDK. // This is in addition to separate filtering in FrameworkScheduler of reserved Marathon volumes. .filter(resource -> ResourceUtils.hasResourceId(resource)) .collect(Collectors.toList()))) .collect(Collectors.toList()); try { recorder.recordCleanupOrUninstall(unexpected); } catch (Exception e) { // Failed to record the upcoming dereservation. Don't return the resources as unexpected until we can record // the dereservation. logger.error("Failed to record unexpected resources", e); return UnexpectedResourcesResponse.failed(Collections.emptyList()); } return UnexpectedResourcesResponse.processed(unexpected); }
private void parseOffer(Offer offer) { // Pull out the cpus, memory, disk, and 2 ports from the offer. for (Resource resource : offer.getResourcesList()) { if (resource.getName().equals("cpus") && resource.getType() == Value.Type.SCALAR) { cpus = resource.getScalar().getValue(); cpuRole = resource.getRole(); } else if (resource.getName().equals("mem") && resource.getType() == Value.Type.SCALAR) { mem = resource.getScalar().getValue(); memRole = resource.getRole(); } else if (resource.getName().equals("disk") && resource.getType() == Value.Type.SCALAR) { disk = resource.getScalar().getValue(); diskRole = resource.getRole(); } else if (resource.getName().equals("ports") && resource.getType() == Value.Type.RANGES) { portRole = resource.getRole(); ports = resource.getRanges().getRangeList(); } } }
private ResourceRequirement simpleScalarRequirement(String name, double minimumRequirement) { return (requirement, taskId, offer) -> { if (ResourceRequirement.scalarSum(offer, name) > minimumRequirement) { return OfferEvaluation.accept( requirement, taskId, offer, Collections.emptyMap(), Collections.emptyList(), Collections.emptyList(), Protos.Resource.newBuilder() .setType(Protos.Value.Type.SCALAR) .setName(name) .setRole(offer.getResourcesList().stream().filter(resource -> resource.getName().equalsIgnoreCase(name)).findFirst().map(Protos.Resource::getRole).orElse("*")) .setScalar(Protos.Value.Scalar.newBuilder().setValue(minimumRequirement)) .build() ); } return OfferEvaluation.decline(requirement, taskId, offer, "Not enough resources for " + name); }; }
@Override public OfferEvaluation check(String requirement, String taskId, Protos.Offer offer) { List<Protos.Resource> roleResources = offer.getResourcesList().stream() .filter(Protos.Resource::hasRole) .filter(resource -> resource.getRole().equals(mesosConfig.getRole())) .collect(Collectors.toList()); if (!roleResources.isEmpty()) { return OfferEvaluation.accept( requirement, taskId, offer, Collections.emptyMap(), Collections.emptyList(), Collections.emptyList(), roleResources ); } return OfferEvaluation.decline(requirement, taskId, offer, "No resources for role " + mesosConfig.getRole()); } }
private Protos.TaskInfo buildCustomizedExecutorTaskInfo(final TaskContext taskContext, final CloudAppConfiguration appConfig, final CloudJobConfiguration jobConfig, final ShardingContexts shardingContexts, final Protos.Offer offer, final Protos.CommandInfo command) { Protos.TaskInfo.Builder result = Protos.TaskInfo.newBuilder().setTaskId(Protos.TaskID.newBuilder().setValue(taskContext.getId()).build()) .setName(taskContext.getTaskName()).setSlaveId(offer.getSlaveId()) .addResources(buildResource("cpus", jobConfig.getCpuCount(), offer.getResourcesList())) .addResources(buildResource("mem", jobConfig.getMemoryMB(), offer.getResourcesList())) .setData(ByteString.copyFrom(new TaskInfoData(shardingContexts, jobConfig).serialize())); Protos.ExecutorInfo.Builder executorBuilder = Protos.ExecutorInfo.newBuilder().setExecutorId(Protos.ExecutorID.newBuilder() .setValue(taskContext.getExecutorId(jobConfig.getAppName()))).setCommand(command) .addResources(buildResource("cpus", appConfig.getCpuCount(), offer.getResourcesList())) .addResources(buildResource("mem", appConfig.getMemoryMB(), offer.getResourcesList())); if (env.getJobEventRdbConfiguration().isPresent()) { executorBuilder.setData(ByteString.copyFrom(SerializationUtils.serialize(env.getJobEventRdbConfigurationMap()))).build(); } return result.setExecutor(executorBuilder.build()).build(); }
private Protos.TaskInfo buildCommandExecutorTaskInfo(final TaskContext taskContext, final CloudJobConfiguration jobConfig, final ShardingContexts shardingContexts, final Protos.Offer offer, final Protos.CommandInfo command) { Protos.TaskInfo.Builder result = Protos.TaskInfo.newBuilder().setTaskId(Protos.TaskID.newBuilder().setValue(taskContext.getId()).build()) .setName(taskContext.getTaskName()).setSlaveId(offer.getSlaveId()) .addResources(buildResource("cpus", jobConfig.getCpuCount(), offer.getResourcesList())) .addResources(buildResource("mem", jobConfig.getMemoryMB(), offer.getResourcesList())) .setData(ByteString.copyFrom(new TaskInfoData(shardingContexts, jobConfig).serialize())); return result.setCommand(command).build(); }
@Override public UnexpectedResourcesResponse answer(InvocationOnMock invocation) throws Throwable { Optional<Protos.Offer> match = getOffersArgument(invocation).stream() .filter(o -> o.getId().equals(unexpectedOffer)) .findAny(); Collection<OfferResources> recs = match.isPresent() ? Collections.singletonList(new OfferResources(match.get()).addAll(match.get().getResourcesList())) : Collections.emptyList(); return UnexpectedResourcesResponse.processed(recs); } };
private int getCpu(final Offer offer) { for (final Resource resource : offer.getResourcesList()) { if (resource.getName().equals("cpus")) { return (int)resource.getScalar().getValue(); } } return 0; }
private int getMemory(final Offer offer) { for (final Resource resource : offer.getResourcesList()) { if (resource.getName().equals("mem")) { return (int)resource.getScalar().getValue(); } } return 0; }
@VisibleForTesting String findRoleForPorts(Offer offer) { String role = MESOS_DEFAULT_ROLE; // Locate the port resource in the offer for (Resource resource : offer.getResourcesList()) { if (resource.getName().equals(PORT_RESOURCE_NAME)) { role = resource.getRole(); } } return role; }
/** * Pretty-print mesos protobuf Offer. * <p/> * XXX(erikdw): not including slave_id, attributes, executor_ids, nor framework_id. */ public static String offerToString(Offer offer) { Map<String, String> map = new LinkedHashMap<>(); map.put("offer_id", offer.getId().getValue()); map.put("hostname", offer.getHostname()); map.putAll(resourcesToOrderedMap(offer.getResourcesList())); return JSONValue.toJSONString(map); }
private static Collection<MesosResource> getMesosResources(Offer offer, Optional<String> role) { Collection<MesosResource> mesosResources = new ArrayList<MesosResource>(); for (Resource resource : offer.getResourcesList()) { if (consumableResource(role, resource)) { mesosResources.add(new MesosResource(resource)); } } return mesosResources; }