2

我们刚刚开始使用弹簧状态机。有几个问题:

  • 每个状态机的状态上下文是否只有一次?
  • 传递给状态机的事件是否以阻塞方式运行?有什么方法可以让它们并行运行,比如每次触发事件时提供一个新的状态机?

这是我的代码:

配置状态和转换:

@Override
public void configure(
        StateMachineTransitionConfigurer<WorkFlowStates, WorkFlowEvent> transitions)
                throws Exception {
    transitions
    .withExternal()
    .source(WorkFlowStates.ready)
    .target(WorkFlowStates.l1Creation)
    .event(WorkFlowEvent.createWorkItem)
    .action(workFlowCreator.createL1())

在状态转换期间提供操作:

public Action<WorkFlowStates, WorkFlowEvent> createL3() {
    return new Action<WorkFlowStates, WorkFlowEvent>() {

        public void execute(StateContext<WorkFlowStates, WorkFlowEvent> context) {
            System.out.println("l3 creation in action");
            Map<Object, Object> variables = context.getExtendedState().getVariables();
            Integer counter = (Integer)variables.get("counter");
            if(counter == null) counter = 1;
            else counter = counter+1;
            variables.put("counter", counter);
            System.out.println("Counter is "+counter);
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            variables.put(Level.l3, WorkItemFactory.createFailureL1L2L3WorkItem());
            variables.put("level", Level.l3);
            System.out.println("l3 created");
        }
    };
}

任务执行者:

public void configure(StateMachineConfigurationConfigurer<WorkFlowStates, 
WorkFlowEvent>config)
                throws Exception {
    config
    .withConfiguration()
    .autoStartup(true)
    .taskExecutor(taskExecutor())
    .listener(new WorkFlowStateMachineListener()); 
}

@Bean(name = StateMachineSystemConstants.TASK_EXECUTOR_BEAN_NAME)
public TaskExecutor taskExecutor() {
    ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
    taskExecutor.afterPropertiesSet();
    taskExecutor.setCorePoolSize(5);
    return taskExecutor;
}

以及传递给状态机的事件:

StateMachine<WorkFlowStates, WorkFlowEvent> stateMachine = 
    context.getBean(StateMachine.class);

    stateMachine.sendEvent(WorkFlowEvent.createWorkItem);
    stateMachine.sendEvent(WorkFlowEvent.createWorkItem);
4

1 回答 1

2

是的,默认行为是阻塞的,因为底层TaskExecutorSyncTaskExecutor. 这可以通过文档中提到的通用配置进行更改。另请参阅默认用于并行执行区域的任务配方。ThreadPoolTaskExecutor

当远离阻塞机器时,您需要注意机器的工作方式以及它何时准备好处理进一步的事件,因为机器可能处于丢弃事件的状态。这通常是您可能需要开始添加延迟事件的时候,以便机器可以在未来更合适的时间处理这些事件。

于 2016-05-06T13:02:31.610 回答