同步执行状态动作 [英] Execute state actions synchronously
问题描述
我正在使用具有多个区域的弹簧状态机,并将某些区域配置为具有entryAction和exitAction.
我最近意识到,动作的回调在不同的线程中运行,有时直到状态转换完成后才完成.
以下是安排操作的时间的堆栈跟踪:
at org.springframework.statemachine.state.AbstractState.entry(AbstractState.java:208)
at org.springframework.statemachine.state.ObjectState.entry(ObjectState.java:156)
at org.springframework.statemachine.support.AbstractStateMachine.entryToState(AbstractStateMachine.java:1216)
at org.springframework.statemachine.support.AbstractStateMachine.entryToState(AbstractStateMachine.java:1161)
at org.springframework.statemachine.support.AbstractStateMachine.setCurrentStateInternal(AbstractStateMachine.java:971)
at org.springframework.statemachine.support.AbstractStateMachine.setCurrentState(AbstractStateMachine.java:949)
at org.springframework.statemachine.support.AbstractStateMachine.setCurrentState(AbstractStateMachine.java:944)
at org.springframework.statemachine.support.AbstractStateMachine.setCurrentStateInternal(AbstractStateMachine.java:1038)
at org.springframework.statemachine.support.AbstractStateMachine.setCurrentState(AbstractStateMachine.java:949)
at org.springframework.statemachine.support.AbstractStateMachine.switchToState(AbstractStateMachine.java:841)
at org.springframework.statemachine.support.AbstractStateMachine.access$400(AbstractStateMachine.java:77)
at org.springframework.statemachine.support.AbstractStateMachine$2.transit(AbstractStateMachine.java:301)
at org.springframework.statemachine.support.DefaultStateMachineExecutor.handleTriggerTrans(DefaultStateMachineExecutor.java:248)
at org.springframework.statemachine.support.DefaultStateMachineExecutor.processTriggerQueue(DefaultStateMachineExecutor.java:395)
at org.springframework.statemachine.support.DefaultStateMachineExecutor.access$100(DefaultStateMachineExecutor.java:61)
at org.springframework.statemachine.support.DefaultStateMachineExecutor$1.run(DefaultStateMachineExecutor.java:281)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
at org.springframework.statemachine.support.DefaultStateMachineExecutor.scheduleEventQueueProcessing(DefaultStateMachineExecutor.java:300)
at org.springframework.statemachine.support.DefaultStateMachineExecutor.execute(DefaultStateMachineExecutor.java:144)
at org.springframework.statemachine.support.AbstractStateMachine.sendEventInternal(AbstractStateMachine.java:559)
at org.springframework.statemachine.support.AbstractStateMachine.sendEvent(AbstractStateMachine.java:211)
为避免争用情况并确保完成sendEvent
函数后状态进入/退出动作已完成,我想使用同步任务调度程序,但我不认为有这种事情(我将不得不实施我自己的).还是有另一种方法可以确保在过渡后完成我的进入/退出操作?
我想使用同步任务计划程序,但是我不认为 有这样的事情.
是的-Spring State Machine使用TaskExecutor来执行区域,默认情况下它是同步的.看起来您正在使用它-您可以在堆栈跟踪中看到它:
org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
还有另一种方法来确保我的进入/退出操作在之后完成 过渡吗?
基本上没有-转换会包装"您要退出的状态的 exit 操作和您要进入的状态的 entry 操作. /p> SM中的
动作有两种类型- state 或 transition 动作.我假设您正在谈论状态进入/退出操作. 这是执行这些类型的操作的顺序顺序.
以下情形是同步执行的:
- 两个状态
A
和B
- 在
A
上执行状态进入和退出操作,在B
上进行状态进入和退出操作 -
A
->B
过渡上的过渡动作
SM处于状态A
-这意味着已经执行了对A
的状态输入操作.我们正在发送一个事件,该事件会触发从A
-> B
的过渡.
Transition started: from: A to: B
Action on transition from A to B //when transition starts, the transition action kicks in, before exiting state A
State A exit action on state //before exiting state A, the state A exit action kicks in
State exited: A
State entered: B
State B entry action on state
Transition ended: from: A to: B
您可以通过向SM配置提供自定义SM侦听器来重现相同的结果.
I am using a spring state machine with multiple regions, and I configure some region to have entryAction and exitAction.
I recently realized that the callback for the actions where run in a different thread and sometimes they don't complete until after the state transition is done.
Here's the stack trace for when the actions get scheduled:
at org.springframework.statemachine.state.AbstractState.entry(AbstractState.java:208)
at org.springframework.statemachine.state.ObjectState.entry(ObjectState.java:156)
at org.springframework.statemachine.support.AbstractStateMachine.entryToState(AbstractStateMachine.java:1216)
at org.springframework.statemachine.support.AbstractStateMachine.entryToState(AbstractStateMachine.java:1161)
at org.springframework.statemachine.support.AbstractStateMachine.setCurrentStateInternal(AbstractStateMachine.java:971)
at org.springframework.statemachine.support.AbstractStateMachine.setCurrentState(AbstractStateMachine.java:949)
at org.springframework.statemachine.support.AbstractStateMachine.setCurrentState(AbstractStateMachine.java:944)
at org.springframework.statemachine.support.AbstractStateMachine.setCurrentStateInternal(AbstractStateMachine.java:1038)
at org.springframework.statemachine.support.AbstractStateMachine.setCurrentState(AbstractStateMachine.java:949)
at org.springframework.statemachine.support.AbstractStateMachine.switchToState(AbstractStateMachine.java:841)
at org.springframework.statemachine.support.AbstractStateMachine.access$400(AbstractStateMachine.java:77)
at org.springframework.statemachine.support.AbstractStateMachine$2.transit(AbstractStateMachine.java:301)
at org.springframework.statemachine.support.DefaultStateMachineExecutor.handleTriggerTrans(DefaultStateMachineExecutor.java:248)
at org.springframework.statemachine.support.DefaultStateMachineExecutor.processTriggerQueue(DefaultStateMachineExecutor.java:395)
at org.springframework.statemachine.support.DefaultStateMachineExecutor.access$100(DefaultStateMachineExecutor.java:61)
at org.springframework.statemachine.support.DefaultStateMachineExecutor$1.run(DefaultStateMachineExecutor.java:281)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
at org.springframework.statemachine.support.DefaultStateMachineExecutor.scheduleEventQueueProcessing(DefaultStateMachineExecutor.java:300)
at org.springframework.statemachine.support.DefaultStateMachineExecutor.execute(DefaultStateMachineExecutor.java:144)
at org.springframework.statemachine.support.AbstractStateMachine.sendEventInternal(AbstractStateMachine.java:559)
at org.springframework.statemachine.support.AbstractStateMachine.sendEvent(AbstractStateMachine.java:211)
To avoid race conditions and make sure that the state entry/exit actions are finished once the sendEvent
function is done, I would like to use a Synchronous task scheduler, but I don't think there's such a thing (I would have to implement my own). Or is there another way to make sure my entry/exit actions are done after the transition?
I would like to use a Synchronous task scheduler, but I don't think there's such a thing.
Yes, there is - Spring State Machine uses TaskExecutor for region executions and by default it's synchronous. And it looks like you are using it - you can see it in your stacktrace:
org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
Is there another way to make sure my entry/exit actions are done after the transition?
Basically no - the transition "wraps" the exit action of the state you're exiting from and the entry action of the state you're entering in.
Actions in the SM are two types - state or transition actions. I assume you're talking about state entry/exit actions. Here's the sequence order in which these types of actions are executed.
The below scenario is executed synchronously:
- two states
A
andB
- state entry and exit action on
A
, state entry and exit action onB
- transition action on the
A
->B
transition
The SM is positioned in state A
- this means that the state entry action on A
is already executed. We're sending an event, which triggers the transition from A
-> B
.
Transition started: from: A to: B
Action on transition from A to B //when transition starts, the transition action kicks in, before exiting state A
State A exit action on state //before exiting state A, the state A exit action kicks in
State exited: A
State entered: B
State B entry action on state
Transition ended: from: A to: B
You can reproduce the same results, supplying a custom SM listener to the SM config.
这篇关于同步执行状态动作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!