Spring StateMachine 可重用的状态机实例

huangapple go评论71阅读模式
英文:

Spring StateMachine reusable statemachine instance

问题

我有一个类似下图的 Spring 状态机:

Spring StateMachine 可重用的状态机实例

我希望在应用启动时启动状态机。然后,在一段时间后(定时),它应该进入 Re-State,再进入带有子状态(GetA、GetB 和 GetC)的 State GetOrders。之后,如果出现错误,它应该进入错误状态;否则,如果一切正常,它应该再次进入 Re-State,并等待定时器。

这是我的配置:

@Override
public void configure(StateMachineConfigurationConfigurer<States, Events> config) throws Exception {
    config.withConfiguration()
          .autoStartup(true)
          .machineId("orderMachine");
}

这是定时器的方法:

@Scheduled(cron = "0 0 1 1 * *")
public void startStateMachine() {
    
    StateMachine<States, Events> sm = factory.getStateMachine();
    sm.start();
    sm.sendEvent(Events.ReState);
}

一切都正常工作,但我注意到每次执行此方法时,启动的状态机具有与上一个状态机不同的 UUID,但 Id 是相同的。因此,我认为我正在创建多个状态机实例。是否可能重用同一状态机,或者没有完成进程?因为在我的情况下,大多数时间状态机的状态应处于 Re-State,可以看作是等待状态。

英文:

I have spring state machine like in the image below:

Spring StateMachine 可重用的状态机实例

I want the state machine to be started at the start of the app. And after that it should go in the Re-State where on some time (Scheduled) it go in State GetOrders with SubStates (GetA, GetB and GetC). After that if there is some error it should go in the error, otherwise if everything is okay it should go in the Re-State where it should wait for the Scheduler.

This is my config

@Override
	public void configure(StateMachineConfigurationConfigurer&lt;States, Events&gt; config) throws Exception {
		config.withConfiguration()
          .autoStartup(true)
          .machineId(&quot;orderMachine&quot;);
	}

And this is the method for the scheduler:

@Scheduled(cron = &quot;0 0 1 1 * *&quot;)
	public void startStateMachine() {
		
		StateMachine&lt;States, Events&gt; sm = factory.getStateMachine();
		sm.start();
		sm.sendEvent(Events.ReState);
	}

Everything is working okay but I have noticed that every time this method executes, the stateMachine that is starting have different UUID with the previous one but the Id is same. So I think I am making multiple instances of the state machine. Is it possible to reuse the same state machine or not finishing the process. Because in my case most of the time the state of the machine should be in Re-State. It can be considered as waiting state.

答案1

得分: 1

尝试使用SpringStateMachineService来获取状态机实例,而不是直接从StateMachineFactory中显式地检索它。您可以使用Spring提供的默认实现

@Bean
public StateMachineService<State, Event> stateMachineService(
        final StateMachineFactory<State, Event> stateMachineFactory) {
    return new DefaultStateMachineService<>(stateMachineFactory);
}

因此,您的代码将如下所示:

@Scheduled(cron = "0 0 1 1 * *")
public void startStateMachine() {
    // 这里需要从某个存储中获取stateMachineId
    stateMachineService.acquireStateMachine(stateMachineId, true)
            .sendEvent(Events.ReState);
}

在上面的代码中,您需要提供特定的状态机标识。通常,我将它们存储在数据库中,查询它们并为每个标识实例化状态机。持久化状态机上下文不在本问题的范围内。请参阅持久化状态机

英文:

Try to use SpringStateMachineService to get a state machine instance instead of explicitly retrieving it from StateMachineFactory. You can use default implementation provided by Spring:

@Bean
public StateMachineService&lt;State, Event&gt; stateMachineService(
        final StateMachineFactory&lt;State, Event&gt; stateMachineFactory) {
    return new DefaultStateMachineService&lt;&gt;(stateMachineFactory);
}

So, your code will look like:

@Scheduled(cron = &quot;0 0 1 1 * *&quot;)
public void startStateMachine() {
    // here we need to get stateMachineId from some storage
    stateMachineService.acquireStateMachine(stateMachineId, true)
            .sendEvent(Events.ReState);
}

In the code above you need to provide particular state machine ids. Usually, I store them in the database, query them and instantiate state machine for each one.
Persisting state machine context is out of scope of the question. See Persisting State Machine

答案2

得分: -1

好的,你的状态机应该是公共的和静态的。这样你可以确保只有一个状态机实例。

英文:

Well your state machine should be most likely public and static. So that you would make sure by that there is only one instance of your machine.

huangapple
  • 本文由 发表于 2020年9月3日 18:31:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/63721812.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定