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