user2330825
user2330825

Reputation: 87

Parallel execution in spring state machine

I'm trying to construct a state machine from thee follwoing UML model using Papyrus. The entryActions for each of the stage is resgistered using DefaultStateMachineComponentResolver , to resolve to respective EntryAction classes in my spring app. My requirement is

1) From the CS stage the execution should fork to two threads, upon getting the triggering event SUCCESS.

2) In one thread DE1 and TE1 should execute sequentially and in the other thread DE2 and TE2 should execute sequentially

3) Transition to END state should happen only if both the threads execute successfully, ie from TE1 a transition should happen to join state signalled by event SUCCESS and from TE2 a transition should happen to join state signalled by event SUCCESS

4) ie. Transition to END state should happen after the successful execution of the 2 threads.

5) While executing each stage if any tasks fails (tasks are written in EntryAction classes), the state machine should navigate to END state , the signals used being FAILURE, TERMINATED (based on the severity of error occured)

Here is the code I used to buildState machine and trigger execution

Builder<String, String> builder = StateMachineBuilder
        .<String, String> builder();
builder.configureConfiguration()
.withConfiguration()
.autoStartup(false)
.listener(listener())
.beanFactory(
        this.applicationContext.getAutowireCapableBeanFactory());//.taskExecutor(taskExecutor());


DefaultStateMachineComponentResolver<String, String> resolver = new DefaultStateMachineComponentResolver<>();
resolver.registerAction("startEntryAction", this.startEntryAction);
resolver.registerAction("apEntryAction", this.apEntryAction);
resolver.registerAction("psEntryAction", this.psEntryAction);
//all entry action classed are registered
...
...
UmlStateMachineModelFactory umlStateMachineModelFactory = new UmlStateMachineModelFactory("classpath:model.uml");
umlStateMachineModelFactory.setStateMachineComponentResolver(resolver);
builder.configureModel().withModel().factory(umlStateMachineModelFactory);

StateMachine<String, String> stateMachine = builder.build();
stateMachine.start()

Issues I faced

1) While using taskExecutor the state machine execution was not getting started.

2)After commenting out the taskExecutor the exectuion was triggered and in the console I got the logs from entryAction classes.

3)In each entry action classes I just added the below code to transit to next state, and for logging purpose

@Override
    public void execute(StateContext<String, String> paramStateContext) {
        LOGGER.debug("Start State entered! ");
        paramStateContext.getStateMachine().sendEvent("SUCCESS"); 
    }

4) But the problem is the state TE1 was never entered, after analysing the logs. My requirement was END state should be entered after executing the tasks in TE1EntryAction and TE2EntryAction

Please find below the logs

[![enter image description here][1]][1]19:03:54.963 DEBUG o.i.r.p.a.StartEntryAction - Start State entered! 
    19:03:55.007 DEBUG o.i.r.p.a.APEntryAction - AP State entered! 
    19:03:55.007 DEBUG o.i.r.p.a.PSEntryAction - PS State entered! 
    19:03:55.007 DEBUG o.i.r.p.a.PBEntryAction - PB State entered! 
    19:03:55.007 DEBUG o.i.r.p.a.CSEntryAction - CS State entered! 
    19:03:55.007 DEBUG o.i.r.p.a.DE1EntryAction - DE1 State entered! 
    19:03:55.007 DEBUG o.i.r.p.a.DE2EntryAction - DE2 State entered! 
    19:03:55.007 DEBUG o.i.r.p.a.TE2EntryAction - TE2 State entered! 
    19:03:55.023 DEBUG o.i.r.p.a.EndStateEntryAction - END State entered! 

Is the problem exists in the UML model I created. if so, how should be the state Diagram look like

Thanks a ton for the help.

enter image description here

Upvotes: 1

Views: 3020

Answers (1)

Janne Valkealahti
Janne Valkealahti

Reputation: 2646

At least your fork/join is wrong as you can't have those without using orthogonal regions.

simple-forkjoin-chart

Source for above is in simple-forkjoin.uml

I'm not sure why papyrus allows you to draw fork/join like that as uml spec clearly states:

Fork Pseudostates serve to split an incoming Transition into two or more Transitions terminating on Vertices in orthogonal Regions of a composite State.

I should probably add model verifier if user is trying to add forks/joins without using regions.

Also I'm not sure what should happen with transition from TE2 to END if machine is waiting join to happen so I'd try to avoid that.

Upvotes: 0

Related Questions