Statemachines forcing your hand even if you are admin

A Statemachine, as defined in MDriven, is a great way to keep the dynamics of an object in order. Set guards and transitions to enforce your business rules. Once you start to use them, you see how your if/then/else code sort of melts away.

You cannot break the rules of the Statemachine - even if you are the developer.

Statemachines -1.png

Going from State1 straight to State3 without passing State2 is impossible - through the framework, that is. You can always update the state attribute in the database.

This rounding of the framework through the database has been acceptable until now.

As we introduced the Slave and HistorySlave MDrivenServer-configurations, we do not want to mess with the database from outside the framework. If we do the change, it will not be recorded in the MDrivenServerSynk table – and thus, it will not propagate to the slaves and will not be recorded with a timestamp in the HistorySlave.

Still, you will get into a situation where you have not interpreted the business correctly – such that you need to fix something by twitching the Statemachines in the production environment.

Earlier today, a user asked me why she could not revive a thing that had been accidentally set to Discarded:

Statemachines -2.png

I did not have a good answer – so I said: donowillfix. Adding the transition took 2 seconds, but the next planned release is 2 weeks away – she needs it Monday. I could do an “out-of-plan release” – but I want to release in the evenings to avoid production disturbance.

Things like this will happen in the future as well.

The solution I decided upon is to introduce an elevation – to allow the developer to bypass the rules of the Statemachines.

This is how to do it:

self.stateMachineForceMode('State');
self.State:='State3'

The new operation stateMachineForceMode(nameofstateattribute) can be called just before attacking the state attribute just as if it had been a normal attribute.

The stateMachineForceMode is only good for 1 write so this will fail on the 3 line:

self.stateMachineForceMode('State');
self.State:='State3';
self.State:='State3'

But this will work:

self.stateMachineForceMode('State');

self.State:='State3';

self.stateMachineForceMode('State');

self.State:='State3'

This is how to force the state from code:

       public void StateMachineForce(string NewState)
       {
           string ForceMode = "self.stateMachineForceMode('TheStateAttribute')";
           string close = "self.TheStateAttribute :='close'";
           string open =  "self.TheStateAttribute='open'";
           Eco.Handles.DefaultEcoSpace es = this.AsIObject().ServiceProvider().GetEcoService<IEcoSpaceService>() as Eco.Handles.DefaultEcoSpace;
           switch (NewState)
           {
               case "close":
                   es.ActionLanguage.Execute(this, ForceMode);
                   es.ActionLanguage.Execute(this, close);
                   break;
               case "open":
                   es.ActionLanguage.Execute(this, ForceMode);
                   es.ActionLanguage.Execute(this, open);
                   break;
               default:
                   break;
           }
This page was edited 160 days ago on 06/17/2024. What links here