Reputation: 3
Background:
In our typical working model of state machine , we use state machine to monitor spring-batch processing done by spring cloud stream micro-services . More precisely saying we create stream ,say, named ItemStream , having source , process , sink micro services deployed that read , process and write records in bulk ; respectively . While doing these activities , we fire REST calls each call consisting of one event in between the operations of streams. These REST calls we consume in State Machine micro-service and fire those events within accordingly , on machine instance . Here at state machine level each time once processing is done , we persist state machine context to the persistent store (database/Redis cache) using JPA/Redis State Machine Persister . And when new REST call is received from streams , we restore back the machine context from the persistent store and populate one fresh state machine object with it ; so as to prepare that fresh machine object to have a state of the machine as existed previously . Note: Here 'populate the fresh state machine object' simply means we create each time new instance using machine factory calls , as we are yet to plug the machine object pool implementation to push and pop used objects of StateMachine as and when needed rather than creating fresh new instance every time .
Problem :
However , now problem we are facing is , we have configured the deferred event (say for e.g.CompleteChunk_1 ) for particular state(e.g. state PROCESSEDCHUNK ) in uml file. Now after firing CompleteChunk_1 event when machine is at PROCESSEDCHUNK state , this event does get deferred i.e. parked aside correctly . Now it is expected that machine should fire this parked event on its own whenever that particular future state(i.e. WRITECHUNK ) is reached for which that event was mapped in a transition . But once machine reaches at that state i.e. at WRITECHUNK state , the machine is not firing that CompleteChunk_1 event on its own which was parked previously in machines deferred list .
Observations
**1.**After trouble shooting the issue what I could notice is State machine's member property 'stateMachineExecutor' holds the DefaultStateMachineExecutor instance who maintains the deferred list in a data structure 'ConcurrentLinkedList' within itself . This executor is every time instantiated to the new one in an onInit() method of state machine in AbstractStateMachine class . So I believe each time whenever fresh instance is created from factory and machine object is revived with the previous persisted context , we are losing the deferred events that were parked in that executor's "deferredList" . Because OOB persistence/restoring does not persist/restore the executor's state thus deferred list present on that executor will be lost . So in our case by the time when machine comes to the correct state i.e. WRITECHUNK , the executor has already lost the deferred event that was parked in past event calls . Thus they can not be now fired by machine automatically because parked events now don't exist in executor.
**2.**In simple state machine examples given on spring documentation I tried to configured deferred events and it worked correctly and after valid state was reached parked events did get fired automatically . In these examples , state machine was launched and running constantly since then from first event to the last event. Thus same instance object of machine holding that same DefaultStateMachineExecutor instance till end worked .
3.Maven dependency lib versions are as below :
a.spring-statemachine-core : 2.0.0 b.spring-statemachine-uml : 2.0.0
Requesting for a Solution ??
So is there any design change needed or a way to deal with this situation of DefaultStateMachineExecutor when looking at the fact that we persist the context and restore it on each REST call that is received ?? Or I am miss understanding something regarding above mentioned conclusions which I have arrived at while troubleshooting ??
Thanking you in advance.
Upvotes: 0
Views: 713
Reputation: 2646
Yes this going to need some changes in a machine itself. It's a little complex issue and generally speaking we need to overhaul other event related things with persistence. These are tracked in gh-550
Upvotes: 1