Wednesday, February 26, 2014

Stateless State Machine

The other day I went to grab a snack in the vending machine at work. I swiped my RFID badge on the reader, waited a few seconds, it showed my balance, and while entering the number of the yummy snack I was ready to consume, the balance went back to zero, which then had the effect of me hitting enter and it displaying “not enough funds, please enter money”.

Knowing full well that a few seconds ago, it showed my balance as being more then plenty, I repeated this process, this time with vigilance in preparing the number ahead of time, so that the second it showed my balance, I could hit enter. Suffice to say, I enjoyed my snack. But this brought to my attention that this state machine didn’t have a path for stopping its pricing update when it had a balance. In other words, a broken state machine.


A state machine is defined as any device that stores the status of something at a given time and can operate on input to change the status and/or an action or output to take place for any given change. That is a great “what is” definition, but what is it really, and how can I make these awesome prone to buggy snippets of code?

Lets start with a basic state machine:
    public class BasicStateMachine
    {
        public string State { get; private set; }

        public void Transition(string state)
        {
            switch (state)
            {
                case "on":
                    State = "ON";
                    OnSwitchedOn();
                    break;
                default:
                    State = "OFF";
                    OnSwitchedOff();
                    break;
            }
        }

        private void OnSwitchedOn()
        {
            // Do something clever
        }

        private void OnSwitchedOff()
        {
            // Stop doing something clever
        }
    }


The above code is pretty straightforward. You have the ability to Transition to states, when the state is set to on, it sets the state to “ON” and fires the OnSwitchedOn method. Anything else attempting to transition will just switch it off.

Now that the “what is a state machine” is taken care of, lets check out a fluent API called Stateless by to do the same thing above, but “better”.

Stateless by Nicholas Blumhardt is a base for exploration of generic and functional programming to drive workflow in .Net. It allows you to create lightweight state machine based workflows directly in code.

On NuGet you will find two packages Stateless and Stateless-4.0. The latter is just a .Net 4.0 complication.

PM> Install-Package stateless-4.0

With Stateless our state machine looks something like this.


    public class StatelessStateMachine
    {
        private readonly StateMachine _stateMachine;

        public enum Trigger
        {
            TurnOn,
            TurnOff
        }

        public enum State
        {
            On,
            Off
        }

        public State Current { get { return _stateMachine.State; } }

        public StatelessStateMachine()
        {
            _stateMachine = new StateMachine(State.Off);
            _stateMachine.Configure(State.Off)
                .Permit(Trigger.TurnOn, State.On)
                .OnEntry(OnSwitchedOff);

            _stateMachine.Configure(State.On)
                .Permit(Trigger.TurnOff, State.Off)
                .OnEntry(OnSwitchedOn);
        }

        public bool Transition(Trigger trigger)
        {
            if (!_stateMachine.CanFire(trigger))
                return false;

            _stateMachine.Fire(trigger);

            return true;
        }
        private void OnSwitchedOn()
        {
            // Do something clever
        }

        private void OnSwitchedOff()
        {
            // Stop doing something clever
        }

    }


Now.. that is a ton more code it looks like, but this is a dynamic system that can grow with need. The State Machine object requires two objects, one for the “State” and one for the “Trigger” or as I like to reference it, the “Transition”.

Going over the Configure section, this is simply setting up that in the “Off” state we are allowed to transition to the “On” state with the “TurnOn” trigger, and finally when the state is entered, call the OnSwitchedOff. There is a point of confusion that can occur here, as with most Fluent API’s. The OnEntry is for the Configure, not the Permit. It might even be more useful later to move the OnEntry above the Permit just to clarify for other people using the code.

Stateless is a great bit of code, the source includes a ton of unit tests (nUnit) as well as a decent amount of samples. It is also really lightweight being 3 total classes (spread out over 13 files) and no external dependencies outside of the BCL. So simple in fact, on one recent project I worked with, I just included the source code, rather than referencing the library to keep down on my dependencies.

I highly recommend heading over to the Google Code Project and giving it a shot!

You can find the code used in this Blog Post on my GitHub Repository.

8 comments:

ragini ragini said...

Thank you a lot for providing individuals with a very spectacular possibility to read critical reviews from this site. Dotnet developer
Authorized Dot Net training in chennai

ragini ragini said...

Thanks for one marvelous posting! I enjoyed reading it; you are a great author. I will make sure to bookmark your blog and may come back someday. I want to encourage that you continue your great posts, xamarin training in Chennai

cynthia williams said...

Very good blog, thanks for sharing such a wonderful blog with us. Keep sharing such worthy information to my vision.
Blockchain Training in Chennai
Blockchain course in Chennai
AWS Training in Chennai
AWS Certification in Chennai
Python Training in Chennai
Python Classes in Chennai

Anbarasan14 said...

Thanks for sharing a worthy information. This is really helpful. Keep doing more.

French Class in Mulund
French Coaching in Mulund
French Classes in Mulund East
French Language Classes in Mulund
French Training in Mulund
French Coaching Classes in Mulund
French Classes in Mulund West

Sadhana Rathore said...

Thanks for sharing this information admin, it helps me to learn new things. Continue sharing more like this.
Appium Training in Chennai
Best Appium Training institute in Chennai
Appium Certification in Chennai
Mobile Appium Training in Chennai
Mobile Appium course in Chennai

Aruna Ram said...

Thank you for sharing such a great concept. I got more knowledge from this blog. Your site was amazing. Keep update on some more details...
Blue Prism Training Bangalore
Blue Prism Classes in Bangalore
Blue Prism Training Centers in Bangalore
Blue Prism Institute in Bangalore
Blue Prism Training in Perambur
Blue Prism Training in Nolambur

LindaJasmine said...

Amazing Post . Thanks for sharing. Your style of writing is very unique. Pls keep on updating.
Spoken English Classes in Chennai
Best Spoken English Classes in Chennai
Spoken English Class in Chennai
Spoken English in Chennai
Best Spoken English Class in Chennai
English Coaching Classes in Chennai

sathyaramesh said...

Selenium Training in Chennai
Selenium Course in Chennai
iOS Course in Chennai
Digital Marketing Training in Chennai
J2EE Training in Chennai
german language classes
german teaching institutes in chennai
german language coaching centres in chennai