Files
spring-cloud-task/spring-cloud-task-docs/src/main/asciidoc/features.adoc
2016-06-16 14:46:51 -04:00

218 lines
8.9 KiB
Plaintext

[[features]]
= Features
[[partintro]]
--
This section goes into more detail about Spring Cloud Task. How to use it, how to
configure it, as well as the appropriate extension points are all covered in this section.
--
[[features-lifecycle]]
== The lifecycle of a Spring Cloud Task
In most cases, the modern cloud environment is designed around the execution of processes
that are not expected to end. If they do, they are typically restarted. While most
platforms do have some method to execute a process that isn't restarted when it ends, the
results of that execution are typically not maintained in a consumable way. Spring Cloud
Task brings the ability to execute short lived processes in an environment and record the
results. This allows for a microservices architecture around short lived processes as
well as longer running services via the integration of tasks by messages.
While this functionality is useful in a cloud environment, the same issues can arise in a
traditional deployment model as well. When executing Spring Boot applications via a
scheduler like cron, it can be useful to be able to monitor the results of the application
after it's completion.
A Spring Cloud Task takes the approach that a Spring Boot application can have a start and an
end and still be successful. Batch applications are just one example of where short lived
processes can be helpful. Spring Cloud Task records lifecycle events of a given task.
The lifecycle consists of a single task execution. This is a physical execution of a
Spring Boot application configured to be a task (annotated with the `@EnableTask`
annotation).
At the beginning of a task (before any `CommandLineRunner` or `ApplicationRunner`
implementations have been executed, an entry in the `TaskRepository` is created recording
the start event. This event is triggered via `SmartLifecycle#start` being triggered by
Spring Framework. This indicates to the system that all beans are ready for use and is
before the execution of any of the `CommandLineRunner` or `ApplicationRunner`
implementations provided by Spring Boot.
NOTE: The recording of a task will only occur upon the successful bootstrapping of an
`ApplicationContext`. If the context fails to bootstrap at all, the task's execution will
not be recorded.
Upon completion of all of the `*Runner#run` calls from Spring Boot or the failure of an
`ApplicationContext` (indicated via a `ApplicationFailedEvent`), the task execution is
updated in the repository with the results.
NOTE: At the completion of a task (all `*Runner#run` methods are called and the task
repository has been updated) the `ApplicationContext` will be closed by default. This
behavior can be overriden by setting the property `spring.cloud.task.closecontext.enabled`
to false.
[[features-task-execution-details]]
=== The TaskExecution
The information stored in the `TaskRepository` is modeled in the `TaskExecution` class and
consists of the following information:
|===
|Field |Description
|`executionid`
|The unique id for the task's execution.
|`exitCode`
|The exit code generated from an `ExitCodeExceptionMapper` implementation. If there is no
exit code generated, but an `ApplicationFailedEvent` is thrown, 1 is set. Otherwise, it's
assumed to be 0.
|`taskName`
|The name for the task as determined by the configured `TaskNameResolver`.
|`startTime`
|The time the task was started as indicated by the `SmartLifecycle#start` call.
|`endTime`
|The time the task was completed as indicated by the `ApplicationReadyEvent`.
|`exitMessage`
|Any information available at the time of exit. If an exception is the cause of the end
of the task (as indicated via an `ApplicationFailedEvent`), the stack trace for that
exception will be stored here.
|`arguments`
|A `List` of the string command line arguments as they were passed into the executable boot
application.
|===
[[features-lifecycle-exit-codes]]
=== Mapping Exit Codes
When a task completes, it will want to return an exit code to the OS. If we take a look
at our original example, we can see that we are not controlling that aspect of our
application. So if an exception is thrown, the JVM will return a code that may or may not
be of any use to you in the debugging of that.
As such, Spring Boot provides an interface, `ExitCodeExceptionMapper` that allows you to
map uncaught exceptions to exit codes. This allows you to be able to indicate at that
level what went wrong. Also, by mapping exit codes in this manner, Spring Cloud Task will
record the exit code returned.
NOTE: While the task is running the exit code will be stored as a null in the repository.
Once complete the appropriate exit code will be stored based on the guidelines enumerated
above.
[[features-configuration]]
== Configuration
Spring Cloud Task provides an out of the box configuration as defined in the
`DefaultTaskConfigurer` and `SimpleTaskConfiguration`. This section will walk through
the defaults as well as how to customize Spring Cloud Task for your needs
[[features-data-source]]
=== DataSource
Spring Cloud Task utilizes a datasource for storing the results of task executions. By
default, we provide an in memory instance of H2 to provide a simple method of
bootstrapping development. However, in a production environment, you'll want to configure
your own `DataSource`.
If your application utilizes only a single `DataSource` and that will serve as both your
business schema as well as the task repository, all you need to do is provide any
`DataSource` (via Spring Boot's configuration conventions is the easiest way). This will
be automatically used by Spring Cloud Task for the repository.
If your application utilizes more than one `DataSource`, you'll need to configure the
task repository with the appropriate `DataSource`. This customization can be done via an
implementation of the `TaskConfigurer`.
[[features-task-configurer]]
=== TaskConfigurer
The `TaskConfigurer` is a strategy interface allowing for users to customize the way
components of Spring Cloud Task are configured. By default, we provide the
`DefaultTaskConfigurer` that provides logical defaults (`Map` based in memory components
useful for development if no `DataSource` is provided and JDBC based components if there
is a `DataSource` available.
The `TaskConfigurer` allows the configuration of three main components:
|===
|Component |Description |Default (provided by `DefaultTaskConfigurer`)
|`TaskRepository`
|The implementation of the `TaskRepository` to be used.
|`SimpleTaskRepository`
|`TaskExplorer`
|The implementation of the `TaskExplorer` (a component for read only access to the task
repository) to be used.
|`SimpleTaskExplorer`
|`PlatformTransactionManager`
|A transaction manager to be used when executing updates for tasks.
|`DataSourceTransactionManager` if a `DataSource` is used,
`ResourcelessTransactionManager` if it is not.
|===
[[features-task-name]]
=== Task Name
In most cases, the name of the task will be the application name as configured via Spring
Boot. However, there are some cases, where you may want to map the run of a task to a
different name. Spring Data Flow is an example of this (where you want the task to be run
with the name of the task definition). Because of this, we offer the ability to customize
how the task is named via the `TaskNameResolver` interface.
By default, Spring Cloud Task provides the `SimpleTaskNameResolver` which will use the
following options (in order of precedence):
. A Spring Boot property (configured any of the ways Spring Boot allows)
`spring.cloud.task.name`.
. The application name as resolved using Spring Boot's rules (obtained via
`ApplicationContext#getId`).
[[features-task-execution-listener]]
=== Task Execution Listener
Allows a user to register listeners for specific events that occur during the task
lifecycle. This is done by creating a class that implements the TaskExecutionListener
interface. The class that implements the `TaskExecutionListener` interface will be
notified for the following events:
. `onTaskStartup` - prior to the storing the `TaskExecution` into the `TaskRepository`
. `onTaskEnd` - prior to the updating of the `TaskExecution` entry in the `TaskRepository`
marking the final state of the task.
. `onTaskFailed` - prior to the `onTaskEnd` method being invoked when an unhandled
exception is thrown by the task.
Spring Cloud Task also allows a user add `TaskExecution` Listeners to methods within a bean
by using the following method annotations:
. `@BeforeTask` - prior to the storing the `TaskExecution` into the `TaskRepository`
. `@AfterTask` - prior to the updating of the `TaskExecution` entry in the `TaskRepository`
marking the final state of the task.
. `@FailedTask` - prior to the `@AfterTask` method being invoked when an unhandled
exception is thrown by the task.
```
public class MyBean {
@BeforeTask
public void methodA(TaskExecution taskExecution) {
}
@AfterTask
public void methodB(TaskExecution taskExecution) {
}
@FailedTask
public void methodC(TaskExecution taskExecution, Throwable throwable) {
}
}
```