@Override public void remove(CeTask task, CeActivityDto.Status status, @Nullable CeTaskResult taskResult, @Nullable Throwable error) { checkArgument(error == null || status == CeActivityDto.Status.FAILED, "Error can be provided only when status is FAILED"); long executionTimeInMs = 0L; try (DbSession dbSession = dbClient.openSession(false)) { CeQueueDto queueDto = dbClient.ceQueueDao().selectByUuid(dbSession, task.getUuid()) .orElseThrow(() -> new IllegalStateException("Task does not exist anymore: " + task)); CeActivityDto activityDto = new CeActivityDto(queueDto); activityDto.setStatus(status); executionTimeInMs = updateExecutionFields(activityDto); updateTaskResult(activityDto, taskResult); updateError(activityDto, error); remove(dbSession, queueDto, activityDto); } finally { updateQueueStatus(status, executionTimeInMs); } }
@Override public int clear() { return cancelAll(true); }
private static void updateError(CeActivityDto activityDto, @Nullable Throwable error) { if (error == null) { return; } if (error instanceof VisitException && error.getCause() != null) { activityDto.setErrorMessage(format("%s (%s)", error.getCause().getMessage(), error.getMessage())); } else { activityDto.setErrorMessage(error.getMessage()); } String stacktrace = getStackTraceForPersistence(error); if (stacktrace != null) { activityDto.setErrorStacktrace(stacktrace); } if (error instanceof TypedException) { activityDto.setErrorType(((TypedException) error).getType()); } }
@Override public void cancelWornOuts() { try (DbSession dbSession = dbClient.openSession(false)) { List<CeQueueDto> wornOutTasks = dbClient.ceQueueDao().selectWornout(dbSession); wornOutTasks.forEach(queueDto -> { CeActivityDto activityDto = new CeActivityDto(queueDto); activityDto.setStatus(CeActivityDto.Status.CANCELED); updateExecutionFields(activityDto); remove(dbSession, queueDto, activityDto); }); } }
@Override public Optional<CeTask> peek(String workerUuid) { requireNonNull(workerUuid, "workerUuid can't be null"); if (computeEngineStatus.getStatus() != ComputeEngineStatus.Status.STARTED || getWorkersPauseStatus() != WorkersPauseStatus.RESUMED) { return Optional.empty(); } try (DbSession dbSession = dbClient.openSession(false)) { CeQueueDao ceQueueDao = dbClient.ceQueueDao(); int i = ceQueueDao.resetToPendingForWorker(dbSession, workerUuid); if (i > 0) { dbSession.commit(); LOG.debug("{} in progress tasks reset for worker uuid {}", i, workerUuid); } Optional<CeQueueDto> opt = ceQueueDao.peek(dbSession, workerUuid); if (opt.isPresent()) { CeQueueDto taskDto = opt.get(); Map<String, ComponentDto> componentsByUuid = loadComponentDtos(dbSession, taskDto); Map<String, String> characteristics = dbClient.ceTaskCharacteristicsDao().selectByTaskUuids(dbSession, singletonList(taskDto.getUuid())).stream() .collect(uniqueIndex(CeTaskCharacteristicDto::getKey, CeTaskCharacteristicDto::getValue)); CeTask task = convertToTask(dbSession, taskDto, characteristics, ofNullable(taskDto.getComponentUuid()).map(componentsByUuid::get).orElse(null), ofNullable(taskDto.getMainComponentUuid()).map(componentsByUuid::get).orElse(null)); queueStatus.addInProgress(); return Optional.of(task); } return Optional.empty(); } }
@Test public void remove_updates_queueStatus_success_even_if_task_does_not_exist_in_DB() { CEQueueStatus queueStatus = mock(CEQueueStatus.class); CeTask task = submit(CeTaskTypes.REPORT, newProjectDto("PROJECT_1")); db.getDbClient().ceQueueDao().deleteByUuid(db.getSession(), task.getUuid()); db.commit(); InternalCeQueueImpl underTest = new InternalCeQueueImpl(system2, db.getDbClient(), null, queueStatus, null, null); try { underTest.remove(task, CeActivityDto.Status.SUCCESS, null, null); fail("remove should have thrown a IllegalStateException"); } catch (IllegalStateException e) { verify(queueStatus).addSuccess(anyLong()); } }
@Override public void cancelWornOuts() { try (DbSession dbSession = dbClient.openSession(false)) { List<CeQueueDto> wornOutTasks = dbClient.ceQueueDao().selectPendingByMinimumExecutionCount(dbSession, MAX_EXECUTION_COUNT); wornOutTasks.forEach(queueDto -> { CeActivityDto activityDto = new CeActivityDto(queueDto); activityDto.setStatus(CeActivityDto.Status.CANCELED); updateQueueStatus(CeActivityDto.Status.CANCELED, activityDto); remove(dbSession, queueDto, activityDto); }); } }
@Test public void cancelWornOuts_does_not_update_queueStatus() { CEQueueStatus queueStatusMock = mock(CEQueueStatus.class); CeTask task = submit(CeTaskTypes.REPORT, newProjectDto("PROJECT_1")); db.executeUpdateSql("update ce_queue set status = 'PENDING', started_at = 123 where uuid = '" + task.getUuid() + "'"); db.commit(); InternalCeQueueImpl underTest = new InternalCeQueueImpl(system2, db.getDbClient(), null, queueStatusMock, null, null); underTest.cancelWornOuts(); assertThat(db.getDbClient().ceActivityDao().selectByUuid(db.getSession(), task.getUuid())).isPresent(); verifyZeroInteractions(queueStatusMock); }
@Test public void remove_updates_queueStatus_failure_even_if_task_does_not_exist_in_DB() { CEQueueStatus queueStatusMock = mock(CEQueueStatus.class); CeTask task = submit(CeTaskTypes.REPORT, newProjectDto("PROJECT_1")); db.getDbClient().ceQueueDao().deleteByUuid(db.getSession(), task.getUuid()); db.commit(); InternalCeQueueImpl underTest = new InternalCeQueueImpl(system2, db.getDbClient(), null, queueStatusMock, null, null); try { underTest.remove(task, CeActivityDto.Status.FAILED, null, null); fail("remove should have thrown a IllegalStateException"); } catch (IllegalStateException e) { verify(queueStatusMock).addError(anyLong()); } }
@Override public void remove(CeTask task, CeActivityDto.Status status, @Nullable CeTaskResult taskResult, @Nullable Throwable error) { checkArgument(error == null || status == CeActivityDto.Status.FAILED, "Error can be provided only when status is FAILED"); try (DbSession dbSession = dbClient.openSession(false)) { CeQueueDto queueDto = dbClient.ceQueueDao().selectByUuid(dbSession, task.getUuid()) .orElseThrow(() -> new IllegalStateException("Task does not exist anymore: " + task)); CeActivityDto activityDto = new CeActivityDto(queueDto); activityDto.setStatus(status); updateQueueStatus(status, activityDto); updateTaskResult(activityDto, taskResult); updateError(activityDto, error); remove(dbSession, queueDto, activityDto); } }
@Override public int clear() { return cancelAll(true); }
private static void updateError(CeActivityDto activityDto, @Nullable Throwable error) { if (error == null) { return; } if (error instanceof VisitException && error.getCause() != null) { activityDto.setErrorMessage(format("%s (%s)", error.getCause().getMessage(), error.getMessage())); } else { activityDto.setErrorMessage(error.getMessage()); } String stacktrace = getStackTraceForPersistence(error); if (stacktrace != null) { activityDto.setErrorStacktrace(stacktrace); } if (error instanceof TypedException) { activityDto.setErrorType(((TypedException) error).getType()); } }