同步执行状态动作 [英] Execute state actions synchronously

查看:97
本文介绍了同步执行状态动作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用具有多个区域的弹簧状态机,并将某些区域配置为具有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 动作.我假设您正在谈论状态进入/退出操作. 这是执行这些类型的操作的顺序顺序.

以下情形是同步执行的:

  • 两个状态AB
  • 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 and B
  • state entry and exit action on A, state entry and exit action on B
  • 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆