@Override public void expect(ClusterState state, SchedulerDriver mockDriver) { Mockito.verify(mockDriver, Mockito.atLeastOnce()).reconcileTasks(Collections.emptyList()); }
/** * 隐式协调. */ public void implicitReconcile() { lock.lock(); try { schedulerDriver.reconcileTasks(Collections.<Protos.TaskStatus>emptyList()); } finally { lock.unlock(); } }
/** * 全量的显示协调. */ public void explicitReconcile() { lock.lock(); try { Set<TaskContext> runningTask = new HashSet<>(); for (Set<TaskContext> each : facadeService.getAllRunningTasks().values()) { runningTask.addAll(each); } if (runningTask.isEmpty()) { return; } log.info("Requesting {} tasks reconciliation with the Mesos master", runningTask.size()); schedulerDriver.reconcileTasks(Collections2.transform(runningTask, new Function<TaskContext, Protos.TaskStatus>() { @Override public Protos.TaskStatus apply(final TaskContext input) { return Protos.TaskStatus.newBuilder() .setTaskId(Protos.TaskID.newBuilder().setValue(input.getId()).build()) .setSlaveId(Protos.SlaveID.newBuilder().setValue(input.getSlaveId()).build()) .setState(Protos.TaskState.TASK_RUNNING).build(); } })); } finally { lock.unlock(); } }
@Override public void expect(ClusterState state, SchedulerDriver mockDriver) { MockitoAnnotations.initMocks(this); Mockito.verify(mockDriver, Mockito.atLeastOnce()).reconcileTasks(statusCaptor.capture()); Set<Protos.TaskStatus> expected = new TreeSet<>(statusComparator); // We only send reconcile calls for tasks that aren't already terminal: expected.addAll(new StateStore(persisterWithStatuses).fetchStatuses().stream() .filter(s -> !TaskUtils.isTerminal(s)) .collect(Collectors.toList())); // Iterate over all reconcile calls, look for any call that had matching arguments. // We do this arg ourselves, since the in-mock comparison never matches. for (Collection<Protos.TaskStatus> reconcileArgs : statusCaptor.getAllValues()) { Set<Protos.TaskStatus> got = new TreeSet<>(statusComparator); got.addAll(reconcileArgs); if (expected.equals(got)) { return; // Found matching call } } Assert.fail(String.format("Expected a task reconcile with arguments: %s, but actual calls were: %s", expected, statusCaptor.getAllValues())); }
isComplete.set(true); } else { Driver.getInstance().reconcileTasks(tasksToReconcile);
@Override public void run() { // performing "explicit" reconciliation; master will respond with the latest state for all logviewer tasks // in the framework scheduler's statusUpdate() method List<TaskStatus> taskStatuses = new ArrayList<TaskStatus>(); List<String> logviewerPaths = _zkClient.getChildren(_logviewerZkDir); if (logviewerPaths == null) { _driver.reconcileTasks(taskStatuses); return; } for (String path : logviewerPaths) { TaskID logviewerTaskId = TaskID.newBuilder() .setValue(new String(_zkClient.getNodeData(String.format("%s/%s", _logviewerZkDir, path)))) .build(); TaskStatus logviewerTaskStatus = TaskStatus.newBuilder() .setTaskId(logviewerTaskId) .setState(TaskState.TASK_RUNNING) .build(); taskStatuses.add(logviewerTaskStatus); } _driver.reconcileTasks(taskStatuses); LOG.info("Performing task reconciliation between scheduler and master on following tasks: {}", taskStatusListToTaskIDsString(taskStatuses)); } }, 0, TASK_RECONCILIATION_INTERVAL); // reconciliation performed every 5 minutes
@Test public void testSingleThread() { reconciler.disableThreading().start(); verify(mockSchedulerDriver).reconcileTasks(Collections.emptyList()); }
@Test public void testScheduledThread() throws InterruptedException { when(mockSchedulerConfig.getImplicitReconcileDelayMs()).thenReturn(0L); when(mockSchedulerConfig.getImplicitReconcilePeriodMs()).thenReturn(1L); reconciler.start(); verify(mockSchedulerDriver, timeout(5000).atLeast(2)).reconcileTasks(Collections.emptyList()); reconciler.stop(); } }
@Test public void testTaskLostToTaskRunningTransition() throws Exception { when(mockStateStore.fetchStatuses()).thenReturn(Collections.singletonList(TASK_STATUS_2)); reconciler.start(); assertFalse(reconciler.isReconciled()); assertEquals(1, reconciler.remaining().size()); reconciler.reconcile(); verify(mockDriver, times(1)).reconcileTasks(Collections.singletonList(TASK_STATUS_2)); assertFalse(reconciler.isReconciled()); assertEquals(1, reconciler.remaining().size()); final Protos.TaskStatus updatedTaskStatus = Protos.TaskStatus.newBuilder(TASK_STATUS_2) .setState(Protos.TaskState.TASK_RUNNING) .build(); reconciler.update(updatedTaskStatus); reconciler.reconcile(); assertTrue(reconciler.isReconciled()); assertEquals(0, reconciler.remaining().size()); }
verify(mockDriver, times(2)).reconcileTasks(taskStatusCaptor.capture()); List<Collection<Protos.TaskStatus>> allCalls = taskStatusCaptor.getAllValues(); assertEquals(2, allCalls.size());
verify(mockSchedulerDriver, times(1)).reconcileTasks( Arrays.asList(getTaskStatus(launchedTaskId, Protos.TaskState.TASK_RUNNING))); statusUpdate(launchedTaskId, Protos.TaskState.TASK_RUNNING);