use of io.kestra.core.models.tasks.retrys.AbstractRetry in project kestra by kestra-io.
the class Worker method run.
private void run(WorkerTask workerTask) throws QueueException {
metricRegistry.counter(MetricRegistry.METRIC_WORKER_STARTED_COUNT, metricRegistry.tags(workerTask)).increment();
if (workerTask.getTaskRun().getState().getCurrent() == State.Type.CREATED) {
metricRegistry.timer(MetricRegistry.METRIC_WORKER_QUEUED_DURATION, metricRegistry.tags(workerTask)).record(Duration.between(workerTask.getTaskRun().getState().getStartDate(), now()));
}
workerTask.logger().info("[namespace: {}] [flow: {}] [task: {}] [execution: {}] [taskrun: {}] [value: {}] Type {} started", workerTask.getTaskRun().getNamespace(), workerTask.getTaskRun().getFlowId(), workerTask.getTaskRun().getTaskId(), workerTask.getTaskRun().getExecutionId(), workerTask.getTaskRun().getId(), workerTask.getTaskRun().getValue(), workerTask.getTask().getClass().getSimpleName());
if (workerTask.logger().isDebugEnabled()) {
workerTask.logger().debug("Variables\n{}", JacksonMapper.log(workerTask.getRunContext().getVariables()));
}
workerTask = workerTask.withTaskRun(workerTask.getTaskRun().withState(State.Type.RUNNING));
this.workerTaskResultQueue.emit(new WorkerTaskResult(workerTask));
if (workerTask.getTask() instanceof RunnableTask) {
// killed cased
if (killedExecution.contains(workerTask.getTaskRun().getExecutionId())) {
workerTask = workerTask.withTaskRun(workerTask.getTaskRun().withState(State.Type.KILLED));
this.workerTaskResultQueue.emit(new WorkerTaskResult(workerTask));
this.logTerminated(workerTask);
return;
}
AtomicReference<WorkerTask> current = new AtomicReference<>(workerTask);
// run
WorkerTask finalWorkerTask = Failsafe.with(AbstractRetry.<WorkerTask>retryPolicy(workerTask.getTask().getRetry()).handleResultIf(result -> result.getTaskRun().lastAttempt() != null && Objects.requireNonNull(result.getTaskRun().lastAttempt()).getState().getCurrent() == State.Type.FAILED).onRetry(e -> {
WorkerTask lastResult = e.getLastResult();
lastResult = lastResult.getRunContext().cleanup(lastResult);
current.set(lastResult);
metricRegistry.counter(MetricRegistry.METRIC_WORKER_RETRYED_COUNT, metricRegistry.tags(current.get(), MetricRegistry.TAG_ATTEMPT_COUNT, String.valueOf(e.getAttemptCount()))).increment();
this.workerTaskResultQueue.emit(new WorkerTaskResult(lastResult));
})).get(() -> this.runAttempt(current.get()));
finalWorkerTask = finalWorkerTask.getRunContext().cleanup(finalWorkerTask);
// get last state
TaskRunAttempt lastAttempt = finalWorkerTask.getTaskRun().lastAttempt();
if (lastAttempt == null) {
throw new IllegalStateException("Can find lastAttempt on taskRun '" + finalWorkerTask.getTaskRun().toString(true) + "'");
}
State.Type state = lastAttempt.getState().getCurrent();
if (workerTask.getTask().getRetry() != null && workerTask.getTask().getRetry().getWarningOnRetry() && finalWorkerTask.getTaskRun().getAttempts().size() > 0 && state == State.Type.SUCCESS) {
state = State.Type.WARNING;
}
// emit
finalWorkerTask = finalWorkerTask.withTaskRun(finalWorkerTask.getTaskRun().withState(state));
// changing status must work in order to finish current task (except if we are near the upper bound size).
try {
this.workerTaskResultQueue.emit(new WorkerTaskResult(finalWorkerTask));
} catch (QueueException e) {
finalWorkerTask = workerTask.withTaskRun(workerTask.getTaskRun().withState(State.Type.FAILED));
this.workerTaskResultQueue.emit(new WorkerTaskResult(finalWorkerTask));
} finally {
this.logTerminated(finalWorkerTask);
}
}
}
Aggregations