Java Code Examples for org.gradle.api.internal.TaskInternal

The following examples show how to use org.gradle.api.internal.TaskInternal. These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
public TaskInternal createTask(Map<String, ?> args) {
    TaskInternal task = taskFactory.createTask(args);
    TaskClassInfo taskClassInfo = getTaskClassInfo(task.getClass());

    if (taskClassInfo.incremental) {
        // Add a dummy upToDateWhen spec: this will for TaskOutputs.hasOutputs() to be true.
        task.getOutputs().upToDateWhen(new Spec<Task>() {
            public boolean isSatisfiedBy(Task element) {
                return true;
            }
        });
    }

    for (Factory<Action<Task>> actionFactory : taskClassInfo.taskActions) {
        task.doFirst(actionFactory.create());
    }

    if (taskClassInfo.validator != null) {
        task.doFirst(taskClassInfo.validator);
        taskClassInfo.validator.addInputsAndOutputs(task);
    }

    return task;
}
 
Example #2
Source Project: pushfish-android   Author: PushFish   File: TaskFactory.java    License: BSD 2-Clause "Simplified" License 6 votes vote down vote up
private TaskInternal createTaskObject(ProjectInternal project, final Class<? extends TaskInternal> type, String name, boolean generateGetters) {
    if (!Task.class.isAssignableFrom(type)) {
        throw new InvalidUserDataException(String.format(
                "Cannot create task of type '%s' as it does not implement the Task interface.",
                type.getSimpleName()));
    }

    final Class<? extends TaskInternal> generatedType;
    if (generateGetters) {
        generatedType = generator.generate(type);
    } else {
        generatedType = type;
    }

    return AbstractTask.injectIntoNewInstance(project, name, new Callable<TaskInternal>() {
        public TaskInternal call() throws Exception {
            try {
                return instantiator.newInstance(generatedType);
            } catch (ObjectInstantiationException e) {
                throw new TaskInstantiationException(String.format("Could not create task of type '%s'.", type.getSimpleName()),
                        e.getCause());
            }
        }
    });
}
 
Example #3
public TaskArtifactState getStateFor(final TaskInternal task) {

        if (!task.getOutputs().getHasOutput()) { // Only false if no declared outputs AND no Task.upToDateWhen spec. We force to true for incremental tasks.
            return new NoHistoryArtifactState();
        }

        final TaskArtifactState state = repository.getStateFor(task);

        if (startParameter.isRerunTasks()) {
            return new RerunTaskArtifactState(state, task, "Executed with '--rerun-tasks'.");
        }

        if (!task.getOutputs().getUpToDateSpec().isSatisfiedBy(task)) {
            return new RerunTaskArtifactState(state, task, "Task.upToDateWhen is false.");
        }

        return state;
    }
 
Example #4
public TaskInternal createTask(Map<String, ?> args) {
    TaskInternal task = taskFactory.createTask(args);
    TaskClassInfo taskClassInfo = getTaskClassInfo(task.getClass());

    if (taskClassInfo.incremental) {
        // Add a dummy upToDateWhen spec: this will for TaskOutputs.hasOutputs() to be true.
        task.getOutputs().upToDateWhen(new Spec<Task>() {
            public boolean isSatisfiedBy(Task element) {
                return true;
            }
        });
    }

    for (Factory<Action<Task>> actionFactory : taskClassInfo.taskActions) {
        task.doFirst(actionFactory.create());
    }

    if (taskClassInfo.validator != null) {
        task.doFirst(taskClassInfo.validator);
        taskClassInfo.validator.addInputsAndOutputs(task);
    }

    return task;
}
 
Example #5
Source Project: Pushjet-Android   Author: Pushjet   File: ValidatingTaskExecuter.java    License: BSD 2-Clause "Simplified" License 6 votes vote down vote up
public void execute(TaskInternal task, TaskStateInternal state, TaskExecutionContext context) {
    List<String> messages = new ArrayList<String>();
    for (TaskValidator validator : task.getValidators()) {
        validator.validate(task, messages);
    }
    if (!messages.isEmpty()) {
        List<InvalidUserDataException> causes = new ArrayList<InvalidUserDataException>();
        messages = messages.subList(0, Math.min(5, messages.size()));
        for (String message : messages) {
            causes.add(new InvalidUserDataException(message));
        }
        String errorMessage;
        if (messages.size() == 1) {
            errorMessage = String.format("A problem was found with the configuration of %s.", task);
        } else {
            errorMessage = String.format("Some problems were found with the configuration of %s.", task);
        }
        state.executed(new TaskValidationException(errorMessage, causes));
        return;
    }
    executer.execute(task, state, context);
}
 
Example #6
public TaskArtifactState getStateFor(final TaskInternal task) {

        if (!task.getOutputs().getHasOutput()) { // Only false if no declared outputs AND no Task.upToDateWhen spec. We force to true for incremental tasks.
            return new NoHistoryArtifactState();
        }

        final TaskArtifactState state = repository.getStateFor(task);

        if (startParameter.isRerunTasks()) {
            return new RerunTaskArtifactState(state, task, "Executed with '--rerun-tasks'.");
        }

        if (!task.getOutputs().getUpToDateSpec().isSatisfiedBy(task)) {
            return new RerunTaskArtifactState(state, task, "Task.upToDateWhen is false.");
        }

        return state;
    }
 
Example #7
Source Project: pushfish-android   Author: PushFish   File: TaskNameResolver.java    License: BSD 2-Clause "Simplified" License 6 votes vote down vote up
/**
 * Finds tasks that will have exactly the given name, without necessarily creating or configuring the tasks. Returns null if no such match found.
 */
@Nullable
public TaskSelectionResult selectWithName(String name, Project project, boolean includeSubProjects) {
    if (!includeSubProjects) {
        TaskInternal task = (TaskInternal) project.getTasks().findByName(name);
        if (task != null) {
            return new FixedTaskSelectionResult(Collections.<Task>singleton(task));
        }
    } else {
        LinkedHashSet<Task> tasks = new LinkedHashSet<Task>();
        new MultiProjectTaskSelectionResult(name, project).collectTasks(tasks);
        if (!tasks.isEmpty()) {
            return new FixedTaskSelectionResult(tasks);
        }
    }

    return null;
}
 
Example #8
public TaskArtifactState getStateFor(final TaskInternal task) {

        if (!task.getOutputs().getHasOutput()) { // Only false if no declared outputs AND no Task.upToDateWhen spec. We force to true for incremental tasks.
            return new NoHistoryArtifactState();
        }

        final TaskArtifactState state = repository.getStateFor(task);

        if (startParameter.isRerunTasks()) {
            return new RerunTaskArtifactState(state, task, "Executed with '--rerun-tasks'.");
        }

        if (!task.getOutputs().getUpToDateSpec().isSatisfiedBy(task)) {
            return new RerunTaskArtifactState(state, task, "Task.upToDateWhen is false.");
        }

        return state;
    }
 
Example #9
public TaskInternal createTask(Map<String, ?> args) {
    TaskInternal task = taskFactory.createTask(args);
    TaskClassInfo taskClassInfo = getTaskClassInfo(task.getClass());

    // TODO:DAZ Make this more general purpose, and support IncrementalTaskActions added via another mechanism.
    if (taskClassInfo.incremental) {
        // Add a dummy upToDateWhen spec: this will for TaskOutputs.hasOutputs() to be true.
        task.getOutputs().upToDateWhen(new Spec<Task>() {
            public boolean isSatisfiedBy(Task element) {
                return true;
            }
        });
    }

    for (Factory<Action<Task>> actionFactory : taskClassInfo.taskActions) {
        task.doFirst(actionFactory.create());
    }

    if (taskClassInfo.validator != null) {
        task.doFirst(taskClassInfo.validator);
        taskClassInfo.validator.addInputsAndOutputs(task);
    }

    return task;
}
 
Example #10
public TaskArtifactState getStateFor(final TaskInternal task) {

        if (!task.getOutputs().getHasOutput()) { // Only false if no declared outputs AND no Task.upToDateWhen spec. We force to true for incremental tasks.
            return new NoHistoryArtifactState();
        }

        final TaskArtifactState state = repository.getStateFor(task);

        if (startParameter.isRerunTasks()) {
            return new RerunTaskArtifactState(state, task, "Executed with '--rerun-tasks'.");
        }

        if (!task.getOutputs().getUpToDateSpec().isSatisfiedBy(task)) {
            return new RerunTaskArtifactState(state, task, "Task.upToDateWhen is false.");
        }

        return state;
    }
 
Example #11
Source Project: pushfish-android   Author: PushFish   File: TaskFactory.java    License: BSD 2-Clause "Simplified" License 6 votes vote down vote up
private TaskInternal createTaskObject(ProjectInternal project, final Class<? extends TaskInternal> type, String name, boolean generateGetters) {
    if (!Task.class.isAssignableFrom(type)) {
        throw new InvalidUserDataException(String.format(
                "Cannot create task of type '%s' as it does not implement the Task interface.",
                type.getSimpleName()));
    }

    final Class<? extends TaskInternal> generatedType;
    if (generateGetters) {
        generatedType = generator.generate(type);
    } else {
        generatedType = type;
    }

    return AbstractTask.injectIntoNewInstance(project, name, new Callable<TaskInternal>() {
        public TaskInternal call() throws Exception {
            try {
                return instantiator.newInstance(generatedType);
            } catch (ObjectInstantiationException e) {
                throw new TaskInstantiationException(String.format("Could not create task of type '%s'.", type.getSimpleName()),
                        e.getCause());
            }
        }
    });
}
 
Example #12
Source Project: pushfish-android   Author: PushFish   File: SkipOnlyIfTaskExecuter.java    License: BSD 2-Clause "Simplified" License 6 votes vote down vote up
public void execute(TaskInternal task, TaskStateInternal state, TaskExecutionContext context) {
    boolean skip;
    try {
        skip = !task.getOnlyIf().isSatisfiedBy(task);
    } catch (Throwable t) {
        state.executed(new GradleException(String.format("Could not evaluate onlyIf predicate for %s.", task), t));
        return;
    }

    if (skip) {
        LOGGER.info("Skipping {} as task onlyIf is false.", task);
        state.skipped("SKIPPED");
        return;
    }

    executer.execute(task, state, context);
}
 
Example #13
Source Project: pushfish-android   Author: PushFish   File: ValidatingTaskExecuter.java    License: BSD 2-Clause "Simplified" License 6 votes vote down vote up
public void execute(TaskInternal task, TaskStateInternal state, TaskExecutionContext context) {
    List<String> messages = new ArrayList<String>();
    for (TaskValidator validator : task.getValidators()) {
        validator.validate(task, messages);
    }
    if (!messages.isEmpty()) {
        List<InvalidUserDataException> causes = new ArrayList<InvalidUserDataException>();
        messages = messages.subList(0, Math.min(5, messages.size()));
        for (String message : messages) {
            causes.add(new InvalidUserDataException(message));
        }
        String errorMessage;
        if (messages.size() == 1) {
            errorMessage = String.format("A problem was found with the configuration of %s.", task);
        } else {
            errorMessage = String.format("Some problems were found with the configuration of %s.", task);
        }
        state.executed(new TaskValidationException(errorMessage, causes));
        return;
    }
    executer.execute(task, state, context);
}
 
Example #14
Source Project: Pushjet-Android   Author: Pushjet   File: TaskFactory.java    License: BSD 2-Clause "Simplified" License 5 votes vote down vote up
public TaskInternal createTask(Map<String, ?> args) {
    Map<String, Object> actualArgs = new HashMap<String, Object>(args);
    checkTaskArgsAndCreateDefaultValues(actualArgs);

    String name = actualArgs.get(Task.TASK_NAME).toString();
    if (!GUtil.isTrue(name)) {
        throw new InvalidUserDataException("The task name must be provided.");
    }

    Class<? extends TaskInternal> type = (Class) actualArgs.get(Task.TASK_TYPE);
    Boolean generateSubclass = Boolean.valueOf(actualArgs.get(GENERATE_SUBCLASS).toString());
    TaskInternal task = createTaskObject(project, type, name, generateSubclass);

    Object dependsOnTasks = actualArgs.get(Task.TASK_DEPENDS_ON);
    if (dependsOnTasks != null) {
        task.dependsOn(dependsOnTasks);
    }
    Object description = actualArgs.get(Task.TASK_DESCRIPTION);
    if (description != null) {
        task.setDescription(description.toString());
    }
    Object group = actualArgs.get(Task.TASK_GROUP);
    if (group != null) {
        task.setGroup(group.toString());
    }
    Object action = actualArgs.get(Task.TASK_ACTION);
    if (action instanceof Action) {
        Action<? super Task> taskAction = (Action<? super Task>) action;
        task.doFirst(taskAction);
    } else if (action != null) {
        Closure closure = (Closure) action;
        task.doFirst(closure);
    }

    return task;
}
 
Example #15
Source Project: pushfish-android   Author: PushFish   File: IncrementalNativeCompiler.java    License: BSD 2-Clause "Simplified" License 5 votes vote down vote up
public IncrementalNativeCompiler(TaskInternal task, TaskArtifactStateCacheAccess cacheAccess, FileSnapshotter fileSnapshotter, Compiler<NativeCompileSpec> delegateCompiler, NativeToolChain toolChain) {
    this.task = task;
    this.cacheAccess = cacheAccess;
    this.fileSnapshotter = fileSnapshotter;
    this.delegateCompiler = delegateCompiler;
    this.importsAreIncludes = Clang.class.isAssignableFrom(toolChain.getClass()) || Gcc.class.isAssignableFrom(toolChain.getClass());
}
 
Example #16
Source Project: Pushjet-Android   Author: Pushjet   File: IncrementalNativeCompiler.java    License: BSD 2-Clause "Simplified" License 5 votes vote down vote up
public IncrementalNativeCompiler(TaskInternal task, TaskArtifactStateCacheAccess cacheAccess, FileSnapshotter fileSnapshotter, Compiler<NativeCompileSpec> delegateCompiler, NativeToolChain toolChain) {
    this.task = task;
    this.cacheAccess = cacheAccess;
    this.fileSnapshotter = fileSnapshotter;
    this.delegateCompiler = delegateCompiler;
    this.importsAreIncludes = Clang.class.isAssignableFrom(toolChain.getClass()) || Gcc.class.isAssignableFrom(toolChain.getClass());
}
 
Example #17
Source Project: pushfish-android   Author: PushFish   File: TaskFactory.java    License: BSD 2-Clause "Simplified" License 5 votes vote down vote up
public TaskInternal createTask(Map<String, ?> args) {
    Map<String, Object> actualArgs = new HashMap<String, Object>(args);
    checkTaskArgsAndCreateDefaultValues(actualArgs);

    String name = actualArgs.get(Task.TASK_NAME).toString();
    if (!GUtil.isTrue(name)) {
        throw new InvalidUserDataException("The task name must be provided.");
    }

    Class<? extends TaskInternal> type = (Class) actualArgs.get(Task.TASK_TYPE);
    Boolean generateSubclass = Boolean.valueOf(actualArgs.get(GENERATE_SUBCLASS).toString());
    TaskInternal task = createTaskObject(project, type, name, generateSubclass);

    Object dependsOnTasks = actualArgs.get(Task.TASK_DEPENDS_ON);
    if (dependsOnTasks != null) {
        task.dependsOn(dependsOnTasks);
    }
    Object description = actualArgs.get(Task.TASK_DESCRIPTION);
    if (description != null) {
        task.setDescription(description.toString());
    }
    Object group = actualArgs.get(Task.TASK_GROUP);
    if (group != null) {
        task.setGroup(group.toString());
    }
    Object action = actualArgs.get(Task.TASK_ACTION);
    if (action instanceof Action) {
        Action<? super Task> taskAction = (Action<? super Task>) action;
        task.doFirst(taskAction);
    } else if (action != null) {
        Closure closure = (Closure) action;
        task.doFirst(closure);
    }

    return task;
}
 
Example #18
Source Project: Pushjet-Android   Author: Pushjet   File: SkipUpToDateTaskExecuter.java    License: BSD 2-Clause "Simplified" License 5 votes vote down vote up
private void logOutOfDateMessages(List<String> messages, TaskInternal task, String took) {
    if (LOGGER.isInfoEnabled()) {
        Formatter formatter = new Formatter();
        formatter.format("Executing %s (up-to-date check took %s) due to:", task, took);
        for (String message : messages) {
            formatter.format("%n  %s", message);
        }
        LOGGER.info(formatter.toString());
    }
}
 
Example #19
Source Project: pushfish-android   Author: PushFish   File: SkipUpToDateTaskExecuter.java    License: BSD 2-Clause "Simplified" License 5 votes vote down vote up
public void execute(TaskInternal task, TaskStateInternal state, TaskExecutionContext context) {
    LOGGER.debug("Determining if {} is up-to-date", task);
    Clock clock = new Clock();
    TaskArtifactState taskArtifactState = repository.getStateFor(task);
    try {
        List<String> messages = new ArrayList<String>();
        if (taskArtifactState.isUpToDate(messages)) {
            LOGGER.info("Skipping {} as it is up-to-date (took {}).", task, clock.getTime());
            state.upToDate();
            return;
        }
        logOutOfDateMessages(messages, task, clock.getTime());

        task.getOutputs().setHistory(taskArtifactState.getExecutionHistory());
        context.setTaskArtifactState(taskArtifactState);

        taskArtifactState.beforeTask();
        try {
            executer.execute(task, state, context);
            if (state.getFailure() == null) {
                taskArtifactState.afterTask();
            }
        } finally {
            task.getOutputs().setHistory(null);
            context.setTaskArtifactState(null);
        }
    } finally {
        taskArtifactState.finished();
    }
}
 
Example #20
Source Project: pushfish-android   Author: PushFish   File: TaskUpToDateState.java    License: BSD 2-Clause "Simplified" License 5 votes vote down vote up
public TaskUpToDateState(TaskInternal task, TaskHistoryRepository.History history, FileCollectionSnapshotter outputFilesSnapshotter, FileCollectionSnapshotter inputFilesSnapshotter) {
    TaskExecution thisExecution = history.getCurrentExecution();
    TaskExecution lastExecution = history.getPreviousExecution();

    noHistoryState = NoHistoryStateChangeRule.create(task, lastExecution);
    taskTypeState = TaskTypeStateChangeRule.create(task, lastExecution, thisExecution);
    inputPropertiesState = InputPropertiesStateChangeRule.create(task, lastExecution, thisExecution);
    outputFilesState = caching(OutputFilesStateChangeRule.create(task, lastExecution, thisExecution, outputFilesSnapshotter));
    inputFilesState = caching(InputFilesStateChangeRule.create(task, lastExecution, thisExecution, inputFilesSnapshotter));
    allTaskChanges = new SummaryTaskStateChanges(MAX_OUT_OF_DATE_MESSAGES, noHistoryState, taskTypeState, inputPropertiesState, outputFilesState, inputFilesState);
    rebuildChanges = new SummaryTaskStateChanges(1, noHistoryState, taskTypeState, inputPropertiesState, outputFilesState);
}
 
Example #21
Source Project: Pushjet-Android   Author: Pushjet   File: SkipUpToDateTaskExecuter.java    License: BSD 2-Clause "Simplified" License 5 votes vote down vote up
private void logOutOfDateMessages(List<String> messages, TaskInternal task, String took) {
    if (LOGGER.isInfoEnabled()) {
        Formatter formatter = new Formatter();
        formatter.format("Executing %s (up-to-date check took %s) due to:", task, took);
        for (String message : messages) {
            formatter.format("%n  %s", message);
        }
        LOGGER.info(formatter.toString());
    }
}
 
Example #22
public void execute(TaskInternal task, TaskStateInternal state, TaskExecutionContext context) {
    if (task.getInputs().getHasSourceFiles() && task.getInputs().getSourceFiles().isEmpty()) {
        LOGGER.info("Skipping {} as it has no source files.", task);
        state.upToDate();
        return;
    }
    executer.execute(task, state, context);
}
 
Example #23
Source Project: Pushjet-Android   Author: Pushjet   File: AbstractTaskPlanExecutor.java    License: BSD 2-Clause "Simplified" License 5 votes vote down vote up
private void executeTask(TaskInfo taskInfo) {
    TaskInternal task = taskInfo.getTask();
    synchronized (lock) {
        taskListener.beforeExecute(task);
    }
    try {
        task.executeWithoutThrowingTaskFailure();
    } finally {
        synchronized (lock) {
            taskListener.afterExecute(task, task.getState());
        }
    }
}
 
Example #24
Source Project: Pushjet-Android   Author: Pushjet   File: TaskFactory.java    License: BSD 2-Clause "Simplified" License 5 votes vote down vote up
public TaskInternal createTask(Map<String, ?> args) {
    Map<String, Object> actualArgs = new HashMap<String, Object>(args);
    checkTaskArgsAndCreateDefaultValues(actualArgs);

    String name = actualArgs.get(Task.TASK_NAME).toString();
    if (!GUtil.isTrue(name)) {
        throw new InvalidUserDataException("The task name must be provided.");
    }

    Class<? extends TaskInternal> type = (Class) actualArgs.get(Task.TASK_TYPE);
    Boolean generateSubclass = Boolean.valueOf(actualArgs.get(GENERATE_SUBCLASS).toString());
    TaskInternal task = createTaskObject(project, type, name, generateSubclass);

    Object dependsOnTasks = actualArgs.get(Task.TASK_DEPENDS_ON);
    if (dependsOnTasks != null) {
        task.dependsOn(dependsOnTasks);
    }
    Object description = actualArgs.get(Task.TASK_DESCRIPTION);
    if (description != null) {
        task.setDescription(description.toString());
    }
    Object group = actualArgs.get(Task.TASK_GROUP);
    if (group != null) {
        task.setGroup(group.toString());
    }
    Object action = actualArgs.get(Task.TASK_ACTION);
    if (action instanceof Action) {
        Action<? super Task> taskAction = (Action<? super Task>) action;
        task.doFirst(taskAction);
    } else if (action != null) {
        Closure closure = (Closure) action;
        task.doFirst(closure);
    }

    return task;
}
 
Example #25
private TaskHistory loadHistory(final TaskInternal task) {
    return cacheAccess.useCache("Load task history", new Factory<TaskHistory>() {
        public TaskHistory create() {
            ClassLoader original = serializer.getClassLoader();
            serializer.setClassLoader(task.getClass().getClassLoader());
            try {
                TaskHistory history = taskHistoryCache.get(task.getPath());
                return history == null ? new TaskHistory() : history;
            } finally {
                serializer.setClassLoader(original);
            }
        }
    });
}
 
Example #26
Source Project: Pushjet-Android   Author: Pushjet   File: NoHistoryStateChangeRule.java    License: BSD 2-Clause "Simplified" License 5 votes vote down vote up
public static TaskStateChanges create(final TaskInternal task, final TaskExecution previousExecution) {
    return new SimpleTaskStateChanges() {
        @Override
        protected void addAllChanges(List<TaskStateChange> changes) {
            if (previousExecution == null) {
                changes.add(new DescriptiveChange("No history is available."));
            }
        }
    };
}
 
Example #27
Source Project: Pushjet-Android   Author: Pushjet   File: ExecuteActionsTaskExecuter.java    License: BSD 2-Clause "Simplified" License 5 votes vote down vote up
private void executeAction(TaskInternal task, ContextAwareTaskAction action, TaskExecutionContext context) {
    action.contextualise(context);
    try {
        action.execute(task);
    } finally {
        action.contextualise(null);
    }
}
 
Example #28
Source Project: pushfish-android   Author: PushFish   File: AbstractTaskPlanExecutor.java    License: BSD 2-Clause "Simplified" License 5 votes vote down vote up
private void executeTask(TaskInfo taskInfo) {
    TaskInternal task = taskInfo.getTask();
    synchronized (lock) {
        taskListener.beforeExecute(task);
    }
    try {
        task.executeWithoutThrowingTaskFailure();
    } finally {
        synchronized (lock) {
            taskListener.afterExecute(task, task.getState());
        }
    }
}
 
Example #29
public void execute(TaskInternal task, TaskStateInternal state, TaskExecutionContext context) {
    if (task.getInputs().getHasSourceFiles() && task.getInputs().getSourceFiles().isEmpty()) {
        LOGGER.info("Skipping {} as it has no source files.", task);
        state.upToDate();
        return;
    }
    executer.execute(task, state, context);
}
 
Example #30
Source Project: Pushjet-Android   Author: Pushjet   File: ExecuteAtMostOnceTaskExecuter.java    License: BSD 2-Clause "Simplified" License 5 votes vote down vote up
public void execute(TaskInternal task, TaskStateInternal state, TaskExecutionContext context) {
    if (state.getExecuted()) {
        return;
    }
    LOGGER.debug("Starting to execute {}", task);
    try {
        executer.execute(task, state, context);
    } finally {
        state.executed();
        LOGGER.debug("Finished executing {}", task);
    }
}