如何从运行时构建的上下文中还原状态机? [英] How to restore state machine from context builded in runtime?

查看:187
本文介绍了如何从运行时构建的上下文中还原状态机?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个状态机

@EnableStateMachine
@Configuration
public class StateMachineConfiguration extends EnumStateMachineConfigurerAdapter<Status, Event> {
    @Override
    public void configure(StateMachineStateConfigurer<Status, Event> states) throws Exception {
        states.withStates()
                .initial(Status.DRAFT)
                .states(EnumSet.allOf(Status.class));
    }

    @Override
    public void configure(StateMachineTransitionConfigurer<Status, Event> transitions) throws Exception {
        transitions

                .withExternal()
                .target(Status.INVITATION).source(Status.DRAFT)
                .event(Event.INVITED)
                .guard(new Guard())
                .action(new ActionInvited())
                .and()

                .withExternal()
                .target(Status.DECLINED).source(Status.INVITATION)
                .event(Event.DECLINED)
                .action(new ActionDeclined());
    }

    @Override
    public void configure(StateMachineConfigurationConfigurer<Status, Event> config) throws Exception {
        config.withConfiguration().autoStartup(true);
    }
}

,我有一个模型,例如 Order . 模型保留在DB中.我从数据库中提取模型,现在我的模型的状态为Order.status == INVITATION.我想继续使用状态机处理模型,但是状态机的实例将以初始状态 DRAFT 开始处理,但是我需要从状态 INVITATION 继续处理.换句话说,我要执行

and I have a model, for example Order. Model persists in DB. I extract model from DB, now my model has a status Order.status == INVITATION. I want to continue processing model with statemachine, but instance of statemachine will starts processing with initial state DRAFT but I needs continue processing from status INVITATION. In other words I want to execute

stateMachine.sendEvent(MessageBuilder
  .withPayload(Event.DECLINED)
  .setHeader("orderId", order.id)
  .build()
)

并执行动作ActionDeclined().我不想在DB中保留状态机的上下文.我想将stateMachine的状态设置为运行时模型的状态.我该如何以正确的方式做到这一点?使用DefaultStateContext构造函数还是还有其他更漂亮的方法?

and execute action ActionDeclined(). I don't want to persist a context of state machine in DB. I want to setting a state of stateMachine to state of my Model in runtime. How can I do that in right way? Using DefaultStateContext constructor or have an other, more beautiful way?

推荐答案

一种可行的方法是动态创建StateMachine,并使用Order的状态从DB重新补充状态机. 在这种情况下,您需要执行以下步骤:

One possible approach is to create the StateMachine on the fly and to rehydrate the state machine from the DB using the state of the Order. In this case you need to do the following steps:

  • Resetting the StateMachine in all regions
  • Load Order status from DB
  • Create new DefaultStateMachineContext and populate accordingly

假设您有一个build方法,该方法将返回用于处理订单事件的新状态机(使用

Let's assume you have a build method, which returns new state machines for processing order events (using a StateMachineFactory), but for an existing order, it will rehydrate the state from the database.

StateMachine<Status, Event> build(long orderId) {
  orderService.getOrder(orderId) //returns Optional
  .map(order -> {
     StateMachine<Status, Event> sm = stateMachineFactory.getStateMachine(Long.toString(orderId));
     sm.stop();
     rehydrateState(sm, sm.getExtendedState(), order.getStatus());
     sm.start();
     return sm;
   })
  .orElseGet(() -> createNewStateMachine(orderId);
}


void rehydrateState(StateMachine<Status, Event> newStateMachine, ExtendedState extendedState, Status orderStatus) {
  newStateMachine.getStateMachineAccessor().doWithAllRegions(sma ->
   sma.resetStateMachine(new DefaultStateMachineContext<>(orderStatus, null, null, extendedState));
  });
}

这篇关于如何从运行时构建的上下文中还原状态机?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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