Override this method to add extra commands that are always handled by this orchestrator (except when recovering).
User overridable callback.
User overridable callback. Its called when a task requests an early termination. Empty default implementation.
the task that initiated the early termination.
the message that caused the early termination.
Map with the tasks status at the moment of early termination.
if you invoke become/unbecome inside this method, the contract that states "Tasks that are waiting will remain untouched and the orchestrator will still be prepared to handle their responses" will no longer be guaranteed.
User overridable callback.
User overridable callback. Its called once every task finishes. By default logs that the Orchestrator has finished then stops it.
You can use this to implement your termination strategy.
Every X messages a snapshot will be saved.
Every X messages a snapshot will be saved. Set to 0 to disable automatic saving of snapshots. By default this method returns the value defined in the configuration.
Roughly every X messages a snapshot will be saved. Set to 0 to disable automatic saving of snapshots. This is just a rough value because the orchestrator will not save it in the snapshots. In fact it will not save it at all. Instead the value of lastSequenceNr will be used to estimate how many messages have been processed.
You can trigger a save snapshot manually by sending a SaveSnapshot message to this orchestrator.
User overridable callback.
User overridable callback. Its called to start the Tasks.
By default logs that the orchestrator started and sends it the StartReadyTasks message.
You can override this to prevent the Orchestrator from starting right away.
However that strategy will only be effective the first time the orchestrator starts, that is,
if this orchestrator restarts with one task already finished, then that task will send the
StartReadyTasks so that tasks that depend on it can start.
(Since version 2.4) use persistAll instead
(Since version 2.4) use persistAllAsync instead
An Orchestrator executes a set of, possibly dependent,
Tasks. A task corresponds to sending a message to an actor, handling its response and possibly mutate the internal state of the Orchestrator.The Orchestrator together with the Task is able to:
NOTE: the responses that are received must be Serializable.
In order for the Orchestrator and the Tasks to be able to achieve all of this they have to access and modify each others state directly. This means they are very tightly coupled with each other. To make this relation more obvious and to enforce it, you will only be able to create tasks inside an orchestrator.
If you have the need to refactor the creation of tasks so that you can use them in multiple orchestrators you can leverage self type annotations like so: