Recipes
本章包含现有内置状态的文档 机器配方。
Spring Statemachine 是一个基础框架。也就是说,它没有太多 更高级别的功能或 Spring Framework 之外的许多依赖项。 因此,正确使用状态机可能很困难。为了提供帮助, 我们创建了一组解决常见使用案例的配方模块。
究竟什么是配方?状态机配方是一个模块,用于解决常见的 用例。从本质上讲,状态机配方既是我们尝试过的一个例子 便于重复使用和扩展。
Recipes 是为 Spring 做外部贡献的好方法 Statemachine 项目。如果您还没有准备好为 framework 核心本身,自定义和通用配方是一个很好的方法 与其他用户共享功能。 |
36. 坚持
persist 配方是一个简单的实用程序,允许您使用单个状态 machine 实例来持久化和更新 存储库。
配方的主类是 ,它做出了三个假设:PersistStateMachineHandler
-
需要使用 a 的实例 替换为 .请注意,状态和事件是必需的 设置为 .
StateMachine<String, String>
PersistStateMachineHandler
String
-
PersistStateChangeListener
需要向 handler 注册 对 persist 请求做出反应。 -
该方法用于编排状态更改。
handleEventWithState
您可以在 Persist 中找到演示如何使用此配方的示例。
37. 任务
任务配方是一个概念,用于运行使用
状态机。这个Recipes是根据引入的想法开发的
在 Tasks 示例中。Runnable
下图显示了状态机的一般概念。在此状态图中,
下的所有内容都显示了单个
任务。因为这个配方允许您注册一个深度
任务的分层 DAG(意味着实际状态图将是一个深
嵌套的子状态和区域的集合),我们不需要
更精确。TASKS
例如,如果您只有两个已注册的任务,则下面的状态图
将是正确的,当替换为 and 时(假设
已注册的任务 ID 为 和 )。TASK_id
TASK_1
TASK_2
1
2
执行 a 可能会导致错误。特别是如果一个复杂的
涉及到 DAG 任务,你要有办法处理
任务执行错误,然后有办法继续执行
而不执行已成功执行的任务。也
如果可以处理一些执行错误就好了
自然而然。作为最后的回退,如果无法处理错误
状态机会自动进入用户可以处理的状态
错误。Runnable
TasksHandler
包含用于配置处理程序实例的 Builder 方法
并遵循简单的构建器模式。您可以使用此构建器
注册 Task 和 Instances 并定义 Hook。Runnable
TasksListener
StateMachinePersist
现在我们可以采用一个运行简单睡眠的简单操作,如下所示
示例显示:Runnable
private Runnable sleepRunnable() {
return new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
}
};
}
前面的示例是本章中所有示例的基础。 |
要执行多个任务,您可以注册任务和
execute 方法,如下例所示:sleepRunnable
runTasks()
TasksHandler
TasksHandler handler = TasksHandler.builder()
.task("1", sleepRunnable())
.task("2", sleepRunnable())
.task("3", sleepRunnable())
.build();
handler.runTasks();
要侦听任务执行中发生的情况,您可以注册一个
a 替换为 .这个Recipes
提供适配器(如果您不想
实现完整接口。监听器提供了各种钩子
侦听任务执行事件。以下示例显示了类的定义:TasksListener
TasksHandler
TasksListenerAdapter
MyTasksListener
private class MyTasksListener extends TasksListenerAdapter {
@Override
public void onTasksStarted() {
}
@Override
public void onTasksContinue() {
}
@Override
public void onTaskPreExecute(Object id) {
}
@Override
public void onTaskPostExecute(Object id) {
}
@Override
public void onTaskFailed(Object id, Exception exception) {
}
@Override
public void onTaskSuccess(Object id) {
}
@Override
public void onTasksSuccess() {
}
@Override
public void onTasksError() {
}
@Override
public void onTasksAutomaticFix(TasksHandler handler, StateContext<String, String> context) {
}
}
您可以使用生成器注册侦听器,也可以直接使用 a 注册侦听器,如下例所示:TasksHandler
MyTasksListener listener1 = new MyTasksListener();
MyTasksListener listener2 = new MyTasksListener();
TasksHandler handler = TasksHandler.builder()
.task("1", sleepRunnable())
.task("2", sleepRunnable())
.task("3", sleepRunnable())
.listener(listener1)
.build();
handler.addTasksListener(listener2);
handler.removeTasksListener(listener2);
handler.runTasks();
每项任务 需要具有唯一标识符,并且(可选)任务可以是 定义为子任务。实际上,这会创建一个任务的 DAG。 以下示例显示如何创建任务的深度嵌套 DAG:
TasksHandler handler = TasksHandler.builder()
.task("1", sleepRunnable())
.task("1", "12", sleepRunnable())
.task("1", "13", sleepRunnable())
.task("2", sleepRunnable())
.task("2", "22", sleepRunnable())
.task("2", "23", sleepRunnable())
.task("3", sleepRunnable())
.task("3", "32", sleepRunnable())
.task("3", "33", sleepRunnable())
.build();
handler.runTasks();
当发生错误并且运行这些任务的状态机进入状态时,您可以调用 handler 方法来
重置保持状态机扩展状态的任务的当前状态
变量。然后,您可以使用 handler 方法执行
指示状态机从 state 转换回 State,您可以在其中再次运行任务。
以下示例显示了如何执行此操作:ERROR
fixCurrentProblems
continueFromError
ERROR
READY
TasksHandler handler = TasksHandler.builder()
.task("1", sleepRunnable())
.task("2", sleepRunnable())
.task("3", sleepRunnable())
.build();
handler.runTasks();
handler.fixCurrentProblems();
handler.continueFromError();