Finite-State Machine – How to Recover from FSM Breakdown

finite-state machineprogramming practicestheory

My question may seems very scientific but I think it's a common problem and seasoned developers and programmers hopefully will have some advice to avoid the problem I mention in title. Btw., what I describe bellow is a real problem I am trying to proactively solve in my iOS project, I want to avoid it at all cost.

By finite state machine I mean this >
I have a UI with a few buttons, several session states relevant to that UI and what this UI represents, I have some data which values are partly displayed in the UI, I receive and handle some external triggers (represented by callbacks from sensors).
I made state diagrams to better map the relevant scenarios that are desirable and alowable in that UI and application.
As I slowly implement the code, the app starts to behave more and more like it should. However, I am not very confident that it is robust enough.
My doubts come from watching my own thinking and implementation process as it goes. I was confident that I had everything covered, but it was enough to make a few brute tests in the UI and I quickly realized that there are still gaps in the behavior ..I patched them.
However, as each component depends and behaves based on input from some other component, a certain input from user or some external source trigers a chain of events, state changes..etc.
I have several components and each behave like this
Trigger received on input -> trigger and its sender analyzed -> output something (a message, a state change) based on analysis

The problem is, this is not completely selfcontained, and my components (a database item, a session state, some button's state)…COULD be changed, influenced, deleted, or otherwise modified, outside the scope of the event-chain or desirable scenario. (phone crashes, battery is empty phone turn of suddenly)
This will introduce a nonvalid situation into the system, from which the system potentially COULD NOT BE ABLE to recover.
I see this (althought people do not realize this is the problem) in many of my competitors apps that are on apple store, customers write things like this>
"I added three documents, and after going there and there, i cannot open them, even if a see them." or "I recorded videos everyday, but after recording a too log video, I cannot turn of captions on them.., and the button for captions doesn't work"..

These are just shortened examples, customers often describe it in more detail..from the descriptions and behavior described in them, I assume that the particular app has a FSM breakdown.

So the ultimate question is how can I avoid this, and how to protect the system from blocking itself?

EDIT> I am talking in the context of one viewcontroller's view on the phone, I mean one part of the application. I Understand the MVC pattern, I have separate modules for distinct functionality..everything I describe is relevant to one canvas on the UI.

Best Answer

I am sure you already know this but just in case:

  1. Make sure every node in the state diagram has an outgoing arc for EVERY legal kind of input (or divide the inputs into classes, with one outbound arc for each class of input).

    Every example I have seen of a state machine uses only one outbound arc for ANY erroneous input.

    If there is no definite answer as to what an input will do every time, it is either an error condition, or there is another input that is missing (that should consistently result an arc for the inputs going to a new node).

    If a node doesn't have an arc for one type of input, then that is an assumption the input will never occur in real life (this is a potential error condition that would not be handled by the state machine).

  2. Make sure the state machine can only take or follow only ONE arc in response to the input received (not more than one arc).

    If there are different kinds of error scenarios, or kinds of inputs that cannot be identified at state machine design time, the error scenarios and unknown inputs should arc to a state with a completely separate path separate from the "normal arcs".

    I.E. if an error or unknown is received in any "known" state, then the arcs followed as a result of the error-handling/unknown input should Not go back into any states the machine would be in if it only received known inputs.

  3. Once you reach a terminal (end) state you shouldn't be able to return to a non-terminal only to the one starting (initial) state.

  4. For one state machine there should not be more than one starting or initial state (based on the examples I've seen).

  5. Based on what I have seen one state machine can only represent the state of one problem or scenario.
    There should never be multiple possible states at one time in one state diagram.
    If I see the potential for multiple concurrent states this tells me I need to split the state diagram up into 2 or more separate state machines that have the potential each state to be independently modified.