当我收到关于我的 API 的请求时,我想执行一系列步骤,每个步骤都是检查或充实。每一步都可能成功,也可能失败。成功后,应执行下一步。失败时,应执行结束步骤,并完成流程。为此,我考虑了 Spring 状态机,因为它似乎符合要求。
我已经阅读了文档并使用了它,但有些事情让我望而却步:
请求和状态机之间是否应该存在一对一的关系,这意味着对于每个请求,我都会创建一个新的状态机实例?或者我应该通过为下一个请求重置机器来以某种方式重用已完成的状态机?
完成状态机的清理怎么样?似乎没有办法销毁和清理状态机实例。如果我为每个请求创建 1 个,我实际上已经引入了内存泄漏,除非框架以某种方式处理资源。
我有一个带有 n 个消息侦听器的事件队列。当消息到达时,一个消息侦听器接收它并执行状态机的一个新实例。我面临的问题是,虽然多条消息是并行处理的,但状态机开始按顺序执行动作,尽管它们是由不同的状态机实例调用的,如下所示:
2017-10-18 16:11:03.740 INFO 30282 --- [lTaskExecutor-1] o.s.s.support.LifecycleObjectSupport : started org.springframework.statemachine.support.DefaultStateMachineExecutor@6ddb1ea6
2017-10-18 16:11:03.741 INFO 30282 --- [lTaskExecutor-1] o.s.s.support.LifecycleObjectSupport : started EVALUATE_IS_WALKTHROUGH SAVE END START / START / uuid=b922b6b1-a441-4924-8531-d45e0e0c9c40 / id=null
2017-10-18 16:11:03.740 INFO 30282 --- [TaskExecutor-10] o.s.s.support.LifecycleObjectSupport : started org.springframework.statemachine.support.DefaultStateMachineExecutor@13b6ace4
2017-10-18 16:11:03.741 INFO 30282 --- [TaskExecutor-10] o.s.s.support.LifecycleObjectSupport : started EVALUATE_IS_WALKTHROUGH SAVE END START / START / uuid=e06a8c1d-beed-41c6-bc63-d8c1a3a56169 / id=null
2017-10-18 16:11:03.759 INFO 30282 --- [pool-5-thread-1] i.b.b.e.processors.actions.SaveAction : [io.botbit.backend.events.processors.actions.SaveAction@607e4071] Saving event Event[id=null,
2017-10-18 16:11:24.046 INFO 30282 --- [pool-5-thread-1] i.b.b.e.processors.actions.SaveAction …Run Code Online (Sandbox Code Playgroud) 我有一个用例,其中事务经历以下多个状态
弹簧状态机是这种流程的正确解决方案吗,还是弹簧可流动更合适。
何时使用 Spring State Machine 或 Spring Flowable 的基本检查是什么。
我试图弄清楚如何轻松使用 Spring 状态机,包括使用 JPA 进行持久化。这是我正在处理的问题:
不兼容的数据类型 - 工厂和持久性
在程序的某个时刻,我想使用连接到用户的状态机。有用于此目的的存储库(项目spring-statemachine-data-jpa)。首先,使用存储库检查玩家的状态机是否已存在。如果没有,则创建一个新的状态机并保留它。
问题是我有不同类型的状态机。工厂创建一个StateMachine<UserState, UserEvent>,存储库返回一个JpaRepositoryStateMachine。这些彼此不兼容,对我来说,不清楚如何持久/创建/恢复状态机。
你能为我澄清一下吗?
@Autowired
private StateMachineRepository<JpaRepositoryStateMachine> repository;
public someMethod(User user) {
Optional<JpaRepositoryStateMachine> stateMachine = repository.findById(user.getId()); // JPA state machine
if(stateMachine.isEmpty()) {
StateMachine<UserState, UserEvent> createdStateMachine = factory.getStateMachine(user.getId()); // spring state machine
repository.save(createdStateMachine); // compile error
}
// here: ready-to-use statemachine - how?
}
Run Code Online (Sandbox Code Playgroud)
感谢您的帮助!
我有简单的状态机跟随States,Events和Transitions.
状态: WIP, SUBMITTED, REJECTED, APPROVED
事件: SUBMIT, APPROVE, REJECT
转变:
@Override
public void configure(StateMachineTransitionConfigurer<States,Events> transitions)
throws Exception {
transitions
.withExternal()
.source(States.WIP)
.target(States.SUBMIT)
.event(Events.SUBMIT)
.and()
.withExternal()
.source(States.SUBMITTED)
.target(States.APPROVED)
.event(Events.APPROVE)
.and()
.withExternal()
.source(States.SUBMITTED)
.target(States.REJECTED)
.event(Events.REJECT);;
}
Run Code Online (Sandbox Code Playgroud)
我已将WIP初始状态设置如下:
@Override
public void configure(StateMachineStateConfigurer<States, Events> states)
throws Exception {
states
.withStates()
.initial(States.WORK_IN_PROGRESS)
.states(EnumSet.allOf(States.class));
}
Run Code Online (Sandbox Code Playgroud)
多个用户将与此状态机进行交互.当源和目标状态的组合多次引发相同的事件时,状态机仅接受第一个事件,不接受后续事件.
这是状态机的有效行为吗?如果是,是否需要添加任何额外配置?
我试图理解,在状态转换期间操作引发的异常是如何可能的。我配置了这个简单的状态机:
transitions
.withExternal()
.source(State.A1)
.target(State.A2)
.event(Event.E1)
.action(executeAnActionThrowingAnException())
Run Code Online (Sandbox Code Playgroud)
在我的服务类中,我注入了我的状态机并发送了这个事件 E1:
@Service
public class MyService() {
@Autowired
private StateMachine<State, Event> stateMachine;
public void executeMyLogic() {
stateMachine.start()
stateMachine.sendEvent(Event.E1);
// how to get thrown exception here
}
}
Run Code Online (Sandbox Code Playgroud)
在我的服务中,我只想知道我的状态机是否以及为什么无法到达 State.A2。因为抛出的异常是由 Spring 状态机获取的,所以我在发送事件后无法得到任何响应。但是状态机没有任何错误,这意味着
stateMachine.hasStateMachineError()
Run Code Online (Sandbox Code Playgroud)
将返回假。那么,我怎样才能在我的服务中获取信息,出现问题,更重要的是什么?
我很感激你的帮助。
此致
11.5配置过渡我们支持三种不同类型的过渡,外部,内部和本地。转换可以通过信号触发,该信号是发送到状态机的事件或计时器。我不知道有什么不同。
我使用Spring Statemachine来提供用户的工作流程.我需要保持状态更改,以便在重新启动时不会丢失用户的状态.现在,我可以根据提供的示例执行此操作,但缺少的一件事是如果发生崩溃,如何重新创建状态.
基本上,我想创建状态机并告诉它将自己设置为崩溃前的最后状态,并从数据库中复制任何扩展状态变量.有没有办法做到这一点?
我正在设置 Spring 状态机事务,我想在 Event1 完成后启动 Event2
这些是我所拥有的状态
状态 ->“初始”、“第二”、“第三”
我已将事务配置为从 FIRST_EVENT 的操作发送 SECOND_EVENT ,如下所示
transitions.withExternal()
.source("INITIAL")
.target("SECOND")
.event("FIRST_EVENT")
.action(new Action<String, String>() {
@Override
public void execute(StateContext<String, String> context) {
System.out.println("FIRST_ACTION_EXECUTED");
context.getStateMachine().sendEvent("SECOND_EVENT");
}
})
.and()
.withExternal()
.source("SECOND")
.target("THIRD")
.event("SECOND_EVENT")
.action(new Action<String, String>() {
@Override
public void execute(StateContext<String, String> context) {
System.out.println("TEST SUCCESS");
}
});
Run Code Online (Sandbox Code Playgroud)
这里我得到了evenNotAccepted异常,我知道原因是statemachine.getState()是INITIAL,并且它不能直接将状态从INITIAL更改为THIRD。
所以我的问题是,我是否可以将状态机配置为在第一个事件完成后自动触发第二个事件
我正在测试 Spring Statemachine,特别是我对应用状态机来管理我的对象的状态很感兴趣。
我的状态机类型为StateMachine<EpisodeState, EpisodeEvent>。
我的业务对象Episode具有类型为 的枚举属性 ( state) EpisodeState,它应该保存剧集的状态机状态。我有一个批处理,它将在初始化时获取一个 Statemachine 的实例。我想遵循基本流程:
Episode从数据库加载一个EpisodeState即在该Episode实例。EpisodeState在我的Episode实例中设置。Episode实例。文档提到了一个extendedState属性,在我的测试中它是空的,但似乎支持任意对象的映射,我想我可以用它来保存我的主键Episode,但我不知道如何设置当前状态状态机中的EpisodeState值Episode。
我已经用 配置了状态机StateMachineInterceptorAdapter<EpisodeState, EpisodeEvent>,我可以在 pre/post stateChange 和 pre/post Transition 以及preEvent.