[[statemachine-recipes]]
= Recipes

This chapter contains documentation for existing built-in state
machine recipes.

Spring Statemachine is a foundational framework. That is, it does not have much
higher-level functionality or many dependencies beyond Spring Framework.
Consequently, correctly using a state machine may be difficult. To help,
we have created a set of recipe modules that address common use cases.

What exactly is a recipe? A state machine recipe is a module that addresses a common
use case. In essence, a state machine recipe is both an example that we have tried to
make it easy for you to reuse and extend.

NOTE: Recipes are a great way to make external contributions to the Spring
Statemachine project. If you are not ready to contribute to the
framework core itself, a custom and common recipe is a great way to
share functionality with other users.

[[statemachine-recipes-persist]]
== Persist

The persist recipe is a simple utility that lets you use a single state
machine instance to persist and update the state of an arbitrary item in
a repository.

The recipe's main class is `PersistStateMachineHandler`, which makes three assumptions:

* An instance of a `StateMachine<String, String>` needs to be used
  with a `PersistStateMachineHandler`. Note that states and Events are required
  to be type of `String`.
* `PersistStateChangeListener` needs to be registered with handler
  to react to persist request.
* The `handleEventWithState` method is used to orchestrate state changes.

You can find a sample that shows how to use this recipe at
<<statemachine-examples-persist>>.

[[statemachine-recipes-tasks]]
== Tasks

The tasks recipe is a concept to run DAG (Directed Acrylic Graph) of `Runnable` instances that use
a state machine. This recipe has been developed from ideas introduced
in <<statemachine-examples-tasks>> sample.

The next image shows the generic concept of a state machine. In this state chart,
everything under `TASKS` shows a generic concept of how a single
task is executed. Because this recipe lets you register a deep
hierarchical DAG of tasks (meaning a real state chart would be a deeply
nested collection of sub-states and regions), we have no need to be
more precise.

For example, if you have only two registered tasks, the following state chart
would be correct when `TASK_id` is replaced with `TASK_1` and `TASK_2` (assuming
the registered tasks IDs are `1` and `2`).

image::images/statechart9.png[width=500]

Executing a `Runnable` may result an error. Especially if a complex
DAG of tasks is involved, you want to have a way to handle
task execution errors and then have a way to continue execution
without executing already successfully executed tasks. Also,
it would be nice if some execution errors can be handled
automatically. As a last fallback, if an error cannot be handled
automatically, the state machine is put into a state where the user can handle
errors manually.

`TasksHandler` contains a builder method to configure a handler instance
and follows a simple builder pattern. You can use this builder to
register `Runnable` tasks and `TasksListener` instances and define
`StateMachinePersist` hook.

Now we can take a simple `Runnable` that runs a simple sleep as the following
example shows:

====
[source,java,indent=0]
----
include::samples/DocsTasksSampleTests.java[tags=snippetAA]
----
====

NOTE: The preceding example is the base for all of the examples in this chapter.

To execute multiple `sleepRunnable` tasks, you can register tasks and
execute `runTasks()` method from `TasksHandler`, as the following example shows:

====
[source,java,indent=0]
----
include::samples/DocsTasksSampleTests.java[tags=snippetB]
----
====

To listen to what is happening with a task execution, you can register an instance of
a `TasksListener` with a `TasksHandler`. This recipe
provides an adapter `TasksListenerAdapter` if you do not want to
implement a full interface. The listener provides a various hooks to
listen tasks execution events. The following example shows the definition of the
`MyTasksListener` class:

====
[source,java,indent=0]
----
include::samples/DocsTasksSampleTests.java[tags=snippetAB]
----
====

You can either register listeners by using a builder or register them directly with a
`TasksHandler` as the following example shows:

====
[source,java,indent=0]
----
include::samples/DocsTasksSampleTests.java[tags=snippetC]
----
====

Every task
needs to have a unique identifier, and (optionally) a task can be
defined to be a sub-task. Effectively, this creates a DAG of tasks.
The following example shows how to create a deep nested DAG of tasks:

====
[source,java,indent=0]
----
include::samples/DocsTasksSampleTests.java[tags=snippetD]
----
====

When an error happens and the state machine running these tasks goes into an
`ERROR` state, you can call `fixCurrentProblems` handler method to
reset the current state of the tasks kept in the state machine's extended state
variables. You can then use the `continueFromError` handler method to
instruct the state machine to transition from the `ERROR` state back to the
`READY` state, where you can again run tasks.
The following example shows how to do so:

====
[source,java,indent=0]
----
include::samples/DocsTasksSampleTests.java[tags=snippetE]
----
====
