Recipes
本章包含现有内置状态的文档 机器配方。
Spring Statemachine 是一个基础框架。也就是说,它没有太多 更高级别的功能或 Spring Framework 之外的许多依赖项。 因此,正确使用状态机可能很困难。为了提供帮助, 我们创建了一组解决常见使用案例的配方模块。
究竟什么是配方?状态机配方是一个模块,用于解决常见的 用例。从本质上讲,状态机配方既是我们尝试过的一个例子 便于重复使用和扩展。
Recipes 是为 Spring 做外部贡献的好方法 Statemachine 项目。如果您还没有准备好为 framework 核心本身,自定义和通用配方是一个很好的方法 与其他用户共享功能。 |
36. 坚持
persist 配方是一个简单的实用程序,允许您使用单个状态 machine 实例来持久化和更新 存储库。
配方的主类是PersistStateMachineHandler
,它做出了三个假设:
-
一个
StateMachine<String, String>
需要使用 替换为PersistStateMachineHandler
.请注意,状态和事件是必需的 To be type ofString
. -
PersistStateChangeListener
需要向 handler 注册 对 persist 请求做出反应。 -
这
handleEventWithState
method 用于编排状态更改。
您可以在 Persist 中找到演示如何使用此配方的示例。
37. 任务
任务配方是一个概念,用于运行 DAG(有向亚克力图)Runnable
使用
状态机。这个Recipes是根据引入的想法开发的
在 Tasks 示例中。
下图显示了状态机的一般概念。在此状态图中,
所有内容TASKS
显示了单个
任务。因为这个配方允许您注册一个深度
任务的分层 DAG(意味着实际状态图将是一个深
嵌套的子状态和区域的集合),我们不需要
更精确。
例如,如果您只有两个已注册的任务,则下面的状态图
当TASK_id
替换为TASK_1
和TASK_2
(假设
已注册的任务 ID 为1
和2
).

执行Runnable
可能会导致错误。特别是如果一个复杂的
涉及到 DAG 任务,你要有办法处理
任务执行错误,然后有办法继续执行
而不执行已成功执行的任务。也
如果可以处理一些执行错误就好了
自然而然。作为最后的回退,如果无法处理错误
状态机会自动进入用户可以处理的状态
错误。
TasksHandler
包含用于配置处理程序实例的 Builder 方法
并遵循简单的构建器模式。您可以使用此构建器
注册Runnable
tasks 和TasksListener
实例并定义StateMachinePersist
钩。
现在我们可以简单地Runnable
运行一个简单的 sleep ,如下所示
示例显示:
private Runnable sleepRunnable() {
return new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
}
};
}
前面的示例是本章中所有示例的基础。 |
要执行多个sleepRunnable
tasks 中,您可以注册 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();
当发生错误并且运行这些任务的状态机进入ERROR
state 中,您可以调用fixCurrentProblems
handler 方法设置为
重置保持状态机扩展状态的任务的当前状态
变量。然后,您可以使用continueFromError
handler 方法设置为
指示状态机从ERROR
state 返回到READY
状态,您可以在其中再次运行任务。
以下示例显示了如何执行此作:
TasksHandler handler = TasksHandler.builder()
.task("1", sleepRunnable())
.task("2", sleepRunnable())
.task("3", sleepRunnable())
.build();
handler.runTasks();
handler.fixCurrentProblems();
handler.continueFromError();