Variations of the State Design Pattern

89 views
Skip to first unread message

Rusi Filipov

unread,
Sep 29, 2015, 3:54:31 PM9/29/15
to Clean Code Discussion
Fellow craftsmen and craftswomen,

Episode 28 introduces a simple convention for the transition between two states. 

For example: Given we are in the locked state, when a coin is inserted, we transition to the unlocked state and invoke the unlock action. Or more formally: X - E/A -> Y is interpreted as: Given state X when event E occurs, we transition to state Y and invoke the action A.

So far so good.

Question 1: Why do we first transition to the new state and then invoke the action, which was defined on the transition? Is there a specific reason to do it in this order? What would be the implication if we first invoke the action and then transition to the new state? For example, how would it affect the an exceptional path? 

a) We are in state X, we receive the event E, we set the new state to Y, we invoke action A, which faults, throwing an exception.

vs.

b) We are in state X, we receive the event E,  we invoke action A, which faults, throwing an exception.

In case a), the FSM is left in state Y after the error, even though the action was not performed. In case b), we would leave the FSM in state X, which might be more appropriate in the error case. But I suspect a) has other advantages. Any ideas?

Question 2: What is an appropriate behavior, if the FSM should be thread-safe and supposed to handle events, coming from multiple threads? Even though the events arrive in parallel, only one event should be processed at a time.

My first approach would be to guard all event-methods with the same mutex during any state transition. In Java, this could be done with synchronized (mutex) blocks within the bodies of the event-methods. Is there a better approach? I was thinking about using an atomic reference for the current state, but this does not seem to be enough for ensuring all events are handled serially.

Question 3: How can we implement a thread-safe FSM, which also processes the events in the order that they arrive? BlockingQueue for the events? Need for a thread for the FSM, or can we do it single-threaded?

Best regards,
Rusi

Sebastian Gozin

unread,
Oct 2, 2015, 5:03:48 AM10/2/15
to Clean Code Discussion
Could you maybe collapse the events from the various threads down into a single thread and operate on the FSM within that single thread?
Y'know, concurrency instead of parallelization.

e.g: each thread is a producer on a queue and there is a single consumer of that queue operating on the FSM.

Indrit Selimi

unread,
Mar 6, 2016, 10:59:54 AM3/6/16
to Clean Code Discussion
Hi Rusi,

1) if the event E is the transition event between states than yes, you call action A on the new state which is now the current state of the FSM and contains appropriate logic for error handling.

Otherwise event E do not transition to the new state but leads to the same initial state and executes logic on the last.

From your description seems that you are referring to guard transitions for which more than one destination state is possible (e.g. internal or external transition).

2) do you have shared program state between threads? This is the question that you should always do before.

Indrit

Reply all
Reply to author
Forward
0 new messages