标签: spring-statemachine

Spring 状态机 - 我应该创建多少?

当我收到关于我的 API 的请求时,我想执行一系列步骤,每个步骤都是检查或充实。每一步都可能成功,也可能失败。成功后,应执行下一步。失败时,应执行结束步骤,并完成流程。为此,我考虑了 Spring 状态机,因为它似乎符合要求。

我已经阅读了文档并使用了它,但有些事情让我望而却步:

  1. 请求和状态机之间是否应该存在一对一的关系,这意味着对于每个请求,我都会创建一个新的状态机实例?或者我应该通过为下一个请求重置机器来以某种方式重用已完成的状态机?

  2. 完成状态机的清理怎么样?似乎没有办法销毁和清理状态机实例。如果我为每个请求创建 1 个,我实际上已经引入了内存泄漏,除非框架以某种方式处理资源。

java spring state-machine spring-statemachine

5
推荐指数
1
解决办法
3434
查看次数

多线程环境下的Spring状态机

我有一个带有 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)

java spring multithreading spring-statemachine

5
推荐指数
1
解决办法
1543
查看次数

Spring Flowable 与状态机,使用哪一个

我有一个用例,其中事务经历以下多个状态

  • 新(初始)
  • 已提交(用户提交事件时)
  • 批准(可以并行运行多个批准,可以通过验证自动批准,也可以通过事件手动批准/拒绝)
  • 已批准(当所有审批任务均处于已批准的最终状态时)
  • 新(当任何一项批准被拒绝时返回新)完成(结束,从已批准自动转换)

弹簧状态机是这种流程的正确解决方案吗,还是弹簧可流动更合适。

何时使用 Spring State Machine 或 Spring Flowable 的基本检查是什么。

spring spring-statemachine

5
推荐指数
0
解决办法
531
查看次数

具有 JPA 持久性的 Spring 状态机 - 存储库使用

我试图弄清楚如何轻松使用 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)

感谢您的帮助!

java spring spring-data-jpa spring-boot spring-statemachine

5
推荐指数
1
解决办法
5301
查看次数

Spring State机器不接受来自多个用户的同一事件

我有简单的状态机跟随States,EventsTransitions.

状态: 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)
  1. WIP为SUBMIT事件提交
  2. 提交批准APPROVE活动
  3. 提交拒绝REJECT活动

我已将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)

多个用户将与此状态机进行交互.当源和目标状态的组合多次引发相同的事件时,状态机仅接受第一个事件,不接受后续事件.

这是状态机的有效行为吗?如果是,是否需要添加任何额外配置?

spring state-machine spring-statemachine

4
推荐指数
1
解决办法
1226
查看次数

如何使用弹簧状态机在状态转换期间抛出异常

我试图理解,在状态转换期间操作引发的异常是如何可能的。我配置了这个简单的状态机:

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)

将返回假。那么,我怎样才能在我的服务中获取信息,出现问题,更重要的是什么?

我很感激你的帮助。

此致

java spring spring-statemachine

4
推荐指数
1
解决办法
1807
查看次数

Transitions内部和本地外部有什么不同?在Spring doc 11.5中配置过渡

11.5配置过渡我们支持三种不同类型的过渡,外部,内部和本地。转换可以通过信号触发,该信号是发送到状态机的事件或计时器。我不知道有什么不同。

spring-statemachine

4
推荐指数
1
解决办法
278
查看次数

如何在特定状态下构建状态机

我使用Spring Statemachine来提供用户的工作流程.我需要保持状态更改,以便在重新启动时不会丢失用户的状态.现在,我可以根据提供的示例执行此操作,但缺少的一件事是如果发生崩溃,如何重新创建状态.

基本上,我想创建状态机并告诉它将自己设置为崩溃前的最后状态,并从数据库中复制任何扩展状态变量.有没有办法做到这一点?

spring spring-boot spring-statemachine

3
推荐指数
2
解决办法
1984
查看次数

无法从操作触发事件

我正在设置 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。

所以我的问题是,我是否可以将状态机配置为在第一个事件完成后自动触发第二个事件

java spring-statemachine

3
推荐指数
1
解决办法
3519
查看次数

Spring 状态机持久化

我正在测试 Spring Statemachine,特别是我对应用状态机来管理我的对象的状态很感兴趣。

我的状态机类型为StateMachine<EpisodeState, EpisodeEvent>

我的业务对象Episode具有类型为 的枚举属性 ( state) EpisodeState,它应该保存剧集的状态机状态。我有一个批处理,它将在初始化时获取一个 Statemachine 的实例。我想遵循基本流程:

  • Episode从数据库加载一个
  • 从设置的statemachine的当前状态,EpisodeState即在该Episode实例。
  • 向状态机发送事件。
  • 从状态机(发布事件)获取结果状态并EpisodeState在我的Episode实例中设置。
  • 保存Episode实例。

文档提到了一个extendedState属性,在我的测试中它是空的,但似乎支持任意对象的映射,我想我可以用它来保存我的主键Episode,但我不知道如何设置当前状态状态机中的EpisodeStateEpisode

我已经用 配置了状态机StateMachineInterceptorAdapter<EpisodeState, EpisodeEvent>,我可以在 pre/post stateChange 和 pre/post Transition 以及preEvent.

spring-statemachine

2
推荐指数
1
解决办法
1182
查看次数