2016-05-06 6 views
0

Wir haben gerade angefangen mit der spring state machine. Haben Sie ein paar Fragen:spring state machine in multi-threaded umgebung

  • Ist der Zustand Kontext nur einmal pro Zustandsmaschine?
  • Werden die an die Statusmaschine übergebenen Ereignisse blockiert? Irgendeine Möglichkeit, sie parallel laufen zu lassen, wie zum Beispiel eine neue Zustandsmaschine bei jedem Auslösen eines Ereignisses bereitzustellen?

Hier ist mein Code:

die Zustände und Übergänge konfigurieren:

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

Bereitstellung von Aktionen während Zustandsübergänge:

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"); 
     } 
    }; 
} 

Testamentsvollstrecker Aufgabe:

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; 
} 

und Ereignisse an die Zustandsmaschine übergeben:

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

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

Antwort

2

Ja, Standardverhalten als zugrunde liegende TaskExecutor ist SyncTaskExecutor blockiert. Dies kann über common config wie in der Dokumentation erwähnt geändert werden. Siehe auch , wobei ThreadPoolTaskExecutor standardmäßig verwendet wird, um Regionen parallel auszuführen.

Wenn Sie sich von einer blockierenden Maschine entfernen, müssen Sie darauf achten, wie die Maschine arbeitet und wann sie bereit ist, weitere Ereignisse zu verarbeiten, da sich die Maschine dann in einem Zustand befindet, in dem Ereignisse verworfen werden. Dies ist normalerweise der Fall, wenn Sie möglicherweise aufgeschobene Ereignisse hinzufügen müssen, damit die Maschine diese in Zukunft zu einem geeigneteren Zeitpunkt verarbeiten kann.

+0

In Ordnung. Irgendwelche Ansichten zu der anderen Frage - "Ist der Zustandskontext nur einmal pro Zustandsmaschine?" – ShankaraNarayanan

+0

Ach ja, Leute mischen normalerweise, was diese Kontexte bedeuten. 'StateContext' ist das, was für einen Übergang erstellt wird, und' StateMachineContext' ist dann ein Kontext auf höherer Ebene, der normalerweise verwendet wird, wenn eine Maschine beibehalten wird. Also nicht genau "einmal pro Maschine". –

+0

Aber der ThreadPoolTaskExecutor ist nur nützlich, wenn wir Aufgaben richtig haben? Wenn ich es mit nur Zuständen ausgeführt habe, blockiert es immer noch. – ShankaraNarayanan