Search in sources :

Example 6 with TaskRun

use of io.kestra.core.models.executions.TaskRun in project kestra by kestra-io.

the class GraphService method fillGraph.

private static void fillGraph(GraphCluster graph, List<Task> tasks, RelationType relationType, TaskRun parent, Execution execution, String value) throws IllegalVariableEvaluationException {
    Iterator<Task> iterator = tasks.iterator();
    AbstractGraphTask previous = graph.getRoot();
    boolean isFirst = true;
    while (iterator.hasNext()) {
        Task currentTask = iterator.next();
        for (TaskRun currentTaskRun : findTaskRuns(currentTask, execution, parent)) {
            AbstractGraphTask currentGraph;
            List<String> parentValues = null;
            // we use the graph relation type by default but we change it to pass relation for case below
            RelationType newRelation = graph.getRelationType();
            if (relationType == RelationType.ERROR) {
                newRelation = relationType;
            } else if ((!isFirst && relationType != RelationType.PARALLEL && graph.getRelationType() != RelationType.DYNAMIC)) {
                newRelation = relationType;
            }
            Relation relation = new Relation(newRelation, currentTaskRun == null ? value : currentTaskRun.getValue());
            if (execution != null && currentTaskRun != null) {
                parentValues = execution.findChildsValues(currentTaskRun, true);
            }
            // detect kind
            if (currentTask instanceof FlowableTask) {
                FlowableTask<?> flowableTask = ((FlowableTask<?>) currentTask);
                currentGraph = flowableTask.tasksTree(execution, currentTaskRun, parentValues);
            } else {
                currentGraph = new GraphTask(currentTask, currentTaskRun, parentValues, relationType);
            }
            // add the node
            graph.getGraph().addNode(currentGraph);
            // link to previous one
            if (previous != null) {
                graph.getGraph().addEdge(previous instanceof GraphCluster ? ((GraphCluster) previous).getEnd() : previous, currentGraph instanceof GraphCluster ? ((GraphCluster) currentGraph).getRoot() : currentGraph, relation);
            }
            // change previous for current one to link
            if (relationType != RelationType.PARALLEL) {
                previous = currentGraph;
            }
            // link to end task
            if (GraphService.isAllLinkToEnd(relationType)) {
                graph.getGraph().addEdge(currentGraph instanceof GraphCluster ? ((GraphCluster) currentGraph).getEnd() : currentGraph, graph.getEnd(), new Relation());
            }
            isFirst = false;
            if (!iterator.hasNext() && !isAllLinkToEnd(relationType)) {
                graph.getGraph().addEdge(currentGraph instanceof GraphCluster ? ((GraphCluster) currentGraph).getEnd() : currentGraph, graph.getEnd(), new Relation());
            }
        }
    }
}
Also used : FlowableTask(io.kestra.core.models.tasks.FlowableTask) Task(io.kestra.core.models.tasks.Task) FlowableTask(io.kestra.core.models.tasks.FlowableTask) TaskRun(io.kestra.core.models.executions.TaskRun)

Example 7 with TaskRun

use of io.kestra.core.models.executions.TaskRun 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);
        }
    }
}
Also used : TaskRun(io.kestra.core.models.executions.TaskRun) java.util(java.util) Getter(lombok.Getter) QueueInterface(io.kestra.core.queues.QueueInterface) JacksonMapper(io.kestra.core.serializers.JacksonMapper) ZonedDateTime(java.time.ZonedDateTime) Hashing(com.google.common.hash.Hashing) AtomicReference(java.util.concurrent.atomic.AtomicReference) State(io.kestra.core.models.flows.State) Timeout(net.jodah.failsafe.Timeout) ApplicationContext(io.micronaut.context.ApplicationContext) ImmutableList(com.google.common.collect.ImmutableList) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TaskRunAttempt(io.kestra.core.models.executions.TaskRunAttempt) Output(io.kestra.core.models.tasks.Output) AbstractRetry(io.kestra.core.models.tasks.retrys.AbstractRetry) Duration(java.time.Duration) ExecutionKilled(io.kestra.core.models.executions.ExecutionKilled) ExecutorService(java.util.concurrent.ExecutorService) Charsets(com.google.common.base.Charsets) Synchronized(lombok.Synchronized) WorkerTaskQueueInterface(io.kestra.core.queues.WorkerTaskQueueInterface) Logger(org.slf4j.Logger) ImmutableMap(com.google.common.collect.ImmutableMap) QueueFactoryInterface(io.kestra.core.queues.QueueFactoryInterface) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Qualifiers(io.micronaut.inject.qualifiers.Qualifiers) IOException(java.io.IOException) Failsafe(net.jodah.failsafe.Failsafe) TimeUnit(java.util.concurrent.TimeUnit) Slf4j(lombok.extern.slf4j.Slf4j) ChronoUnit(java.time.temporal.ChronoUnit) Await(io.kestra.core.utils.Await) ExecutorsUtils(io.kestra.core.utils.ExecutorsUtils) QueueException(io.kestra.core.queues.QueueException) TimeoutExceededException(io.kestra.core.exceptions.TimeoutExceededException) Closeable(java.io.Closeable) MetricRegistry(io.kestra.core.metrics.MetricRegistry) RunnableTask(io.kestra.core.models.tasks.RunnableTask) TaskRunAttempt(io.kestra.core.models.executions.TaskRunAttempt) State(io.kestra.core.models.flows.State) QueueException(io.kestra.core.queues.QueueException) AtomicReference(java.util.concurrent.atomic.AtomicReference) RunnableTask(io.kestra.core.models.tasks.RunnableTask)

Example 8 with TaskRun

use of io.kestra.core.models.executions.TaskRun in project kestra by kestra-io.

the class ExecutionService method replay.

public Execution replay(final Execution execution, String taskRunId, @Nullable Integer revision) throws Exception {
    if (!execution.getState().isTerninated()) {
        throw new IllegalStateException("Execution must be terminated to be restarted, " + "current state is '" + execution.getState().getCurrent() + "' !");
    }
    final Flow flow = flowRepositoryInterface.findByExecution(execution);
    GraphCluster graphCluster = GraphService.of(flow, execution);
    Set<String> taskRunToRestart = this.taskRunWithAncestors(execution, execution.getTaskRunList().stream().filter(taskRun -> taskRun.getId().equals(taskRunId)).collect(Collectors.toList()));
    if (taskRunToRestart.size() == 0) {
        throw new IllegalArgumentException("No task found to restart execution from !");
    }
    Map<String, String> mappingTaskRunId = this.mapTaskRunId(execution, false);
    final String newExecutionId = IdUtils.create();
    List<TaskRun> newTaskRuns = execution.getTaskRunList().stream().map(throwFunction(originalTaskRun -> this.mapTaskRun(flow, originalTaskRun, mappingTaskRunId, newExecutionId, State.Type.RESTARTED, taskRunToRestart.contains(originalTaskRun.getId())))).collect(Collectors.toList());
    Set<String> taskRunToRemove = GraphService.successors(graphCluster, List.of(taskRunId)).stream().filter(task -> task.getTaskRun() != null).filter(task -> !task.getTaskRun().getId().equals(taskRunId)).filter(task -> !taskRunToRestart.contains(task.getTaskRun().getId())).map(s -> mappingTaskRunId.get(s.getTaskRun().getId())).collect(Collectors.toSet());
    taskRunToRemove.forEach(r -> newTaskRuns.removeIf(taskRun -> taskRun.getId().equals(r)));
    // Build and launch new execution
    Execution newExecution = execution.childExecution(newExecutionId, newTaskRuns, execution.withState(State.Type.RESTARTED).getState());
    return revision != null ? newExecution.withFlowRevision(revision) : newExecution;
}
Also used : TaskRun(io.kestra.core.models.executions.TaskRun) java.util(java.util) Rethrow.throwFunction(io.kestra.core.utils.Rethrow.throwFunction) Singleton(jakarta.inject.Singleton) Execution(io.kestra.core.models.executions.Execution) Collectors(java.util.stream.Collectors) InternalException(io.kestra.core.exceptions.InternalException) State(io.kestra.core.models.flows.State) IdUtils(io.kestra.core.utils.IdUtils) ApplicationContext(io.micronaut.context.ApplicationContext) Stream(java.util.stream.Stream) TaskRunAttempt(io.kestra.core.models.executions.TaskRunAttempt) Nullable(io.micronaut.core.annotation.Nullable) Flow(io.kestra.core.models.flows.Flow) Inject(jakarta.inject.Inject) GraphCluster(io.kestra.core.models.hierarchies.GraphCluster) FlowRepositoryInterface(io.kestra.core.repositories.FlowRepositoryInterface) TaskRun(io.kestra.core.models.executions.TaskRun) GraphCluster(io.kestra.core.models.hierarchies.GraphCluster) Execution(io.kestra.core.models.executions.Execution) Flow(io.kestra.core.models.flows.Flow)

Example 9 with TaskRun

use of io.kestra.core.models.executions.TaskRun in project kestra by kestra-io.

the class ExecutorService method childWorkerTaskResult.

private Optional<WorkerTaskResult> childWorkerTaskResult(Flow flow, Execution execution, TaskRun parentTaskRun) throws InternalException {
    Task parent = flow.findTaskByTaskId(parentTaskRun.getTaskId());
    if (parent instanceof FlowableTask) {
        FlowableTask<?> flowableParent = (FlowableTask<?>) parent;
        RunContext runContext = runContextFactory.of(flow, parent, execution, parentTaskRun);
        // first find the normal ended child tasks and send result
        Optional<WorkerTaskResult> endedTask = childWorkerTaskTypeToWorkerTask(flowableParent.resolveState(runContext, execution, parentTaskRun), parent, parentTaskRun);
        if (endedTask.isPresent()) {
            return endedTask;
        }
        // after if the execution is KILLING, we find if all already started tasks if finished
        if (execution.getState().getCurrent() == State.Type.KILLING) {
            // first notified the parent taskRun of killing to avoid new creation of tasks
            if (parentTaskRun.getState().getCurrent() != State.Type.KILLING) {
                return childWorkerTaskTypeToWorkerTask(Optional.of(State.Type.KILLING), parent, parentTaskRun);
            }
            // Then wait for completion (KILLED or whatever) on child taks to KILLED the parennt one.
            List<ResolvedTask> currentTasks = execution.findTaskDependingFlowState(flowableParent.childTasks(runContext, parentTaskRun), FlowableUtils.resolveTasks(flowableParent.getErrors(), parentTaskRun));
            List<TaskRun> taskRunByTasks = execution.findTaskRunByTasks(currentTasks, parentTaskRun);
            if (taskRunByTasks.stream().filter(t -> t.getState().isTerninated()).count() == taskRunByTasks.size()) {
                return childWorkerTaskTypeToWorkerTask(Optional.of(State.Type.KILLED), parent, parentTaskRun);
            }
        }
    }
    return Optional.empty();
}
Also used : FlowableTask(io.kestra.core.models.tasks.FlowableTask) TaskRun(io.kestra.core.models.executions.TaskRun) NextTaskRun(io.kestra.core.models.executions.NextTaskRun) ResolvedTask(io.kestra.core.models.tasks.ResolvedTask) Task(io.kestra.core.models.tasks.Task) FlowableTask(io.kestra.core.models.tasks.FlowableTask) ResolvedTask(io.kestra.core.models.tasks.ResolvedTask)

Example 10 with TaskRun

use of io.kestra.core.models.executions.TaskRun in project kestra by kestra-io.

the class ExecutorService method handleChildNext.

private Executor handleChildNext(Executor executor) throws InternalException {
    if (executor.getExecution().getTaskRunList() == null) {
        return executor;
    }
    List<TaskRun> running = executor.getExecution().getTaskRunList().stream().filter(taskRun -> taskRun.getState().isRunning()).collect(Collectors.toList());
    // Remove functionnal style to avoid (class io.kestra.core.exceptions.IllegalVariableEvaluationException cannot be cast to class java.lang.RuntimeException'
    ArrayList<TaskRun> result = new ArrayList<>();
    for (TaskRun taskRun : running) {
        result.addAll(this.childNextsTaskRun(executor, taskRun));
    }
    if (result.size() == 0) {
        return executor;
    }
    return executor.withTaskRun(result, "handleChildNext");
}
Also used : TaskRun(io.kestra.core.models.executions.TaskRun) Logger(org.slf4j.Logger) Rethrow.throwFunction(io.kestra.core.utils.Rethrow.throwFunction) ImmutableMap(com.google.common.collect.ImmutableMap) ConditionService(io.kestra.core.services.ConditionService) Singleton(jakarta.inject.Singleton) Execution(io.kestra.core.models.executions.Execution) Collectors(java.util.stream.Collectors) InternalException(io.kestra.core.exceptions.InternalException) ResolvedTask(io.kestra.core.models.tasks.ResolvedTask) State(io.kestra.core.models.flows.State) ArrayList(java.util.ArrayList) Task(io.kestra.core.models.tasks.Task) Slf4j(lombok.extern.slf4j.Slf4j) List(java.util.List) NextTaskRun(io.kestra.core.models.executions.NextTaskRun) ApplicationContext(io.micronaut.context.ApplicationContext) Optional(java.util.Optional) Flow(io.kestra.core.models.flows.Flow) MetricRegistry(io.kestra.core.metrics.MetricRegistry) Inject(jakarta.inject.Inject) FlowableTask(io.kestra.core.models.tasks.FlowableTask) TaskRun(io.kestra.core.models.executions.TaskRun) NextTaskRun(io.kestra.core.models.executions.NextTaskRun) ArrayList(java.util.ArrayList)

Aggregations

TaskRun (io.kestra.core.models.executions.TaskRun)23 Execution (io.kestra.core.models.executions.Execution)14 Flow (io.kestra.core.models.flows.Flow)9 State (io.kestra.core.models.flows.State)8 Test (org.junit.jupiter.api.Test)6 NextTaskRun (io.kestra.core.models.executions.NextTaskRun)5 Task (io.kestra.core.models.tasks.Task)5 Inject (jakarta.inject.Inject)5 java.util (java.util)5 ImmutableMap (com.google.common.collect.ImmutableMap)4 TaskRunAttempt (io.kestra.core.models.executions.TaskRunAttempt)4 FlowableTask (io.kestra.core.models.tasks.FlowableTask)4 AbstractMemoryRunnerTest (io.kestra.core.runners.AbstractMemoryRunnerTest)4 Duration (java.time.Duration)4 InternalException (io.kestra.core.exceptions.InternalException)3 QueueFactoryInterface (io.kestra.core.queues.QueueFactoryInterface)3 QueueInterface (io.kestra.core.queues.QueueInterface)3 FlowRepositoryInterface (io.kestra.core.repositories.FlowRepositoryInterface)3 TimeoutExceededException (io.kestra.core.exceptions.TimeoutExceededException)2 MetricRegistry (io.kestra.core.metrics.MetricRegistry)2