/** {@inheritDoc} */ @Override public synchronized void resourceOffers(SchedulerDriver schedulerDriver, List<Protos.Offer> offers) { log.log(Level.FINE, "Offers resources: {0}", offers.size()); for (Protos.Offer offer : offers) { IgniteTask igniteTask = checkOffer(offer); // Decline offer which doesn't match by mem or cpu. if (igniteTask == null) { schedulerDriver.declineOffer(offer.getId()); continue; } // Generate a unique task ID. Protos.TaskID taskId = Protos.TaskID.newBuilder() .setValue(Integer.toString(taskIdGenerator.incrementAndGet())).build(); log.log(Level.INFO, "Launching task: {0}", igniteTask); // Create task to run. Protos.TaskInfo task = createTask(offer, igniteTask, taskId); try { schedulerDriver.launchTasks(Collections.singletonList(offer.getId()), Collections.singletonList(task), Protos.Filters.newBuilder().setRefuseSeconds(1).build()); } catch (RuntimeException e) { log.log(Level.SEVERE, "Failed launch task. Task id: {0}. Task info: {1}", new Object[]{taskId, task, e}); throw e; } tasks.put(taskId.getValue(), igniteTask); } }
@Override public void expect(ClusterState state, SchedulerDriver mockDriver) { ArgumentCaptor<Protos.OfferID> offerIdCaptor = ArgumentCaptor.forClass(Protos.OfferID.class); Set<String> lastCycleOfferIds = state.getLastOfferCycle().stream() .map(o -> o.getId().getValue()) .collect(Collectors.toSet()); Mockito.verify(mockDriver, Mockito.atLeast(lastCycleOfferIds.size())).declineOffer(offerIdCaptor.capture(), any()); // Check that the offer ids from the last cycle were all declined: Set<String> declinedOfferIds = offerIdCaptor.getAllValues().stream() .map(o -> o.getValue()) .collect(Collectors.toSet()); Assert.assertTrue( String.format("Expected all offers from last offer cycle to be declined: %s, got: %s", lastCycleOfferIds, declinedOfferIds), declinedOfferIds.containsAll(lastCycleOfferIds)); }
/** * Decline unused {@link org.apache.mesos.Protos.Offer}s. * * @param unusedOffers The collection of Offers to decline * @param refuseSeconds The number of seconds for which the offers should be refused */ private static void declineOffers(Collection<Protos.Offer> unusedOffers, int refuseSeconds) { Collection<Protos.OfferID> offerIds = unusedOffers.stream() .map(offer -> offer.getId()) .collect(Collectors.toList()); LOGGER.info("Declining {} unused offer{} for {} seconds: {}", offerIds.size(), offerIds.size() == 1 ? "" : "s", refuseSeconds, offerIds.stream().map(Protos.OfferID::getValue).collect(Collectors.toList())); final Protos.Filters filters = Protos.Filters.newBuilder() .setRefuseSeconds(refuseSeconds) .build(); offerIds.forEach(offerId -> Driver.getInstance().declineOffer(offerId, filters)); }
@Override public void call(final VirtualMachineLease lease) { log.warn("Declining offer on '{}'", lease.hostname()); schedulerDriver.declineOffer(lease.getOffer().getId()); } }).build();
int maxSlots = ro.getMaxSlots(); if (maxSlots == 0) { schedulerDriver.declineOffer(offer.getId()); return; if (tip == null) { if (tasks.isEmpty()) { schedulerDriver.declineOffer(offer.getId());
@Override public void resourceOffers(SchedulerDriver driver, List<Offer> offers) { LOGGER.log(Level.FINE, "Received offers {0}", offers.size()); // if we have resource offers, we check for avaiable tasks checkForNewTasks(); for (Offer offer : offers) { boolean matched = false; for (Request request : requests) { if (matches(offer, request)) { matched = true; LOGGER.info("Offer matched! Creating mesos task"); try { createMesosTask(offer, request); } catch (IOException ex) { LOGGER.log(Level.SEVERE, null, ex); } requests.remove(request); break; } } if (!matched) { driver.declineOffer(offer.getId()); } } }
/** * Handle a resource offer by the mesos framework * * @param schedulerDriver The mesos scheduler driver * @param offers A list of offers from mesos */ public void resourceOffers(SchedulerDriver schedulerDriver, List<Offer> offers) { if (tasksToRun.isEmpty()) { // there is no need to track executing tasks if everything is // started clearQueues(); for (Offer offer : offers) { schedulerDriver.declineOffer(offer.getId()); } } else { for (Offer offer : offers) { useOffer(schedulerDriver, offer); } } }
public void resourceOffers(SchedulerDriver driver, List<Protos.Offer> offers) { synchronized (_offersLock) { if (_offers == null) { return; } LOG.debug("resourceOffers: Currently have {} offers buffered {}", _offers.size(), (_offers.size() > 0 ? (":" + offerMapToString(_offers)) : "")); for (Protos.Offer offer : offers) { if (isHostAccepted(offer.getHostname())) { // TODO(ksoundararaj): Should we record the following as info instead of debug LOG.info("resourceOffers: Recording offer: {}", offerToString(offer)); _offers.put(offer.getId(), offer); } else { LOG.info("resourceOffers: Declining offer: {}", offerToString(offer)); driver.declineOffer(offer.getId()); } } LOG.info("resourceOffers: After processing offers, now have {} offers buffered: {}", _offers.size(), offerMapToString(_offers)); } }
@Override public void resourceOffers(SchedulerDriver schedulerDriver, List<Protos.Offer> offers) { logger.info("Initiating new offer round of " + offers.size() + " offers"); AtomicInteger acceptedOffers = new AtomicInteger(0); AtomicInteger rejectedOffers = new AtomicInteger(0); offers.stream() .peek(offer -> logger.debug("Received offerId=" + offer.getId().getValue() + " for slaveId=" + offer.getSlaveId().getValue())) .map(offer -> offerStrategyFilter.evaluate(uuidSupplier.get().toString(), offer)) .peek(offerEvaluation -> (offerEvaluation.isValid() ? acceptedOffers : rejectedOffers).incrementAndGet()) .filter(StreamHelper.onNegative( OfferEvaluation::isValid, offerEvaluation -> schedulerDriver.declineOffer(offerEvaluation.getOffer().getId()))) .peek(offerEvaluation -> logger.info("Accepting offer offerId=" + offerEvaluation.getOffer().getId().getValue() + " on slaveId=" + offerEvaluation.getOffer().getSlaveId().getValue())) .map(taskMaterializer::createProposal) // .peek(taskProposal -> logger.debug("Launching task " + taskProposal.getTaskInfo().toString())) .forEach(taskProposal -> { schedulerDriver.launchTasks(Collections.singleton(taskProposal.getOfferId()), Collections.singleton(taskProposal.getTaskInfo())); stateRepository.store(taskProposal.taskInfo); }); logger.info("Finished evaluating " + offers.size() + " offers. Accepted " + acceptedOffers.get() + " offers and rejected " + rejectedOffers.get()); }
private void declineOffer(Offer offer, double duration) { LOGGER.fine("Rejecting offer " + offer.getId().getValue() + " for " + duration + " seconds"); Filters filters = Filters.newBuilder().setRefuseSeconds(duration).build(); driver.declineOffer(offer.getId(), filters); }
@Test public void testDeclineCall() { final List<Protos.Offer> offers = Arrays.asList(getOffer()); final List<Protos.OfferID> offerIds = offers.stream().map(Protos.Offer::getId).collect(Collectors.toList()); Driver.setDriver(mockSchedulerDriver); OfferProcessor.declineShort(offers); verify(mockSchedulerDriver).declineOffer(eq(offerIds.get(0)), any()); }
@Test public void testOffersUnused() throws InterruptedException { when(mockMesosEventClient.offers(any())).thenReturn(OfferResponse.processed(Collections.emptyList())); when(mockMesosEventClient.getUnexpectedResources(any())) .thenReturn(UnexpectedResourcesResponse.processed(Collections.emptyList())); processor.setOfferQueueSize(0).start(); // unlimited queue size // All offers should have been declined with a long interval (don't need these, come back much later): Set<String> sentOfferIds = sendOffers(1, OFFERS_PER_THREAD); verify(mockSchedulerDriver, times(sentOfferIds.size())).declineOffer(any(), eq(LONG_INTERVAL)); }
@Test public void testOffersNotReady() throws InterruptedException { when(mockMesosEventClient.offers(any())).thenReturn(OfferResponse.notReady(Collections.emptyList())); when(mockMesosEventClient.getUnexpectedResources(any())) .thenReturn(UnexpectedResourcesResponse.processed(Collections.emptyList())); processor.setOfferQueueSize(0).start(); // unlimited queue size // All offers should have been declined with a short interval (not ready, come back soon): Set<String> sentOfferIds = sendOffers(1, OFFERS_PER_THREAD); verify(mockSchedulerDriver, times(sentOfferIds.size())).declineOffer(any(), eq(SHORT_INTERVAL)); }
@Test public void testAsyncOffersLimitedQueueSize() throws InterruptedException { when(mockMesosEventClient.offers(any())).thenReturn(OfferResponse.processed(Collections.emptyList())); when(mockMesosEventClient.getUnexpectedResources(any())) .thenReturn(UnexpectedResourcesResponse.processed(Collections.emptyList())); processor.setOfferQueueSize(10).start(); // At least some offers should have been dropped/declined before reaching the client: Set<String> sentOfferIds = sendOffers(THREAD_COUNT, OFFERS_PER_THREAD); verify(mockMesosEventClient, atLeastOnce()).offers(any()); verify(mockMesosEventClient, atMost(sentOfferIds.size() - 1)).offers(any()); verify(mockSchedulerDriver, atLeastOnce()).declineOffer(any(), any()); }
@Test public void testEmptyOffers() throws Exception { UninstallScheduler uninstallScheduler = getUninstallScheduler(); Assert.assertEquals(ClientStatusResponse.launching(true), uninstallScheduler.getClientStatus()); Assert.assertEquals(OfferResponse.Result.PROCESSED, uninstallScheduler.offers(Collections.emptyList()).result); verify(mockSchedulerDriver, times(0)).acceptOffers(any(), any(), any()); verify(mockSchedulerDriver, times(0)).declineOffer(any(), any()); }
@Test public void willDeclineOfferIfStrategyDeclinesOffer() { Protos.Offer offer = newOffer("host1").build(); when(offerStrategy.evaluate(offer)).thenReturn(OfferStrategy.OfferResult.decline("Test")); when(frameworkState.isRegistered()).thenReturn(true); scheduler.resourceOffers(driver, singletonList(offer)); verify(driver).declineOffer(offer.getId()); }
@Test public void testOfferReadiness() { Driver.setDriver(mockSchedulerDriver); List<Protos.Offer> offers = Arrays.asList(getOffer(), getOffer(), getOffer()); // Offers tossed within the scheduler, not passed to the processor: scheduler.resourceOffers(mockSchedulerDriver, offers); verify(mockSchedulerDriver, times(3)).declineOffer(any(), eq(SHORT_INTERVAL)); verify(mockOfferProcessor, never()).enqueue(any()); scheduler.setApiServerStarted(); // Offers passed to the processor: scheduler.resourceOffers(mockSchedulerDriver, offers); verify(mockOfferProcessor).enqueue(offers); }
@Test public void testAsyncOffersUnlimitedQueueSize() throws InterruptedException { // The queueing results in accumulating all the offer lists into a flat list. // So we need to explicitly collect an offer count. AtomicInteger receivedCount = new AtomicInteger(0); when(mockMesosEventClient.offers(any())).thenAnswer(new Answer<OfferResponse>() { @Override public OfferResponse answer(InvocationOnMock invocation) throws Throwable { List<Protos.Offer> offers = getOffersArgument(invocation); receivedCount.addAndGet(offers.size()); // Consume all the offers: return OfferResponse.processed(offers.stream() .map(offer -> new ReserveOfferRecommendation(offer, ResourceTestUtils.getUnreservedCpus(3))) .collect(Collectors.toList())); } }); when(mockMesosEventClient.getUnexpectedResources(any())) .thenReturn(UnexpectedResourcesResponse.processed(Collections.emptyList())); processor.setOfferQueueSize(0).start(); // unlimited queue size // No offers should have been dropped/declined: Set<String> sentOfferIds = sendOffers(THREAD_COUNT, OFFERS_PER_THREAD); Assert.assertEquals(receivedCount.get(), sentOfferIds.size()); verify(mockSchedulerDriver, never()).declineOffer(any(), any()); }
@Test public void testAcceptedAndUnexpectedResources() throws InterruptedException { List<Protos.Offer> sentOffers = Arrays.asList(getOffer(), getOffer(), getOffer()); List<Protos.OfferID> sentOfferIds = sentOffers.stream().map(o -> o.getId()).collect(Collectors.toList()); Protos.OfferID offerToConsume = sentOfferIds.get(0); Protos.OfferID offerToUnreserve = sentOfferIds.get(2); when(mockMesosEventClient.offers(any())).thenAnswer(consumeOffer(offerToConsume)); when(mockMesosEventClient.getUnexpectedResources(any())).thenAnswer(unexpectedOffer(offerToUnreserve)); processor.setOfferQueueSize(0).start(); // unlimited queue size processor.enqueue(sentOffers); processor.awaitOffersProcessed(); // One declined offer, one reserved offer, one unreserved offer: verify(mockSchedulerDriver, times(1)).declineOffer(sentOfferIds.get(1), LONG_INTERVAL); verify(mockSchedulerDriver, times(1)).acceptOffers(offerIdCaptor.capture(), operationCaptor.capture(), any()); Assert.assertEquals(new HashSet<>(Arrays.asList(offerToConsume, offerToUnreserve)), offerIdCaptor.getValue()); List<Protos.Offer.Operation> operations = operationCaptor.getValue(); Assert.assertEquals(2, operations.size()); Assert.assertEquals(Protos.Offer.Operation.Type.RESERVE, operations.get(0).getType()); Assert.assertEquals(Protos.Offer.Operation.Type.UNRESERVE, operations.get(1).getType()); }
mesosMaster.launchTasks(Collections.singleton(offer.getId()), tasksToLaunch, filters); } else { mesosMaster.declineOffer(offer.getId());