Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

State Machine in Python: Run Code in Transition or State?

I am rather new to the python language, please bear with me on this one.

I want to run two state machines in two separate threads, communicating to each other via a queue. I used the transitions package to create the state machine.

My understanding is that all actions/code that performs actions has to be tucked into the transactions.

These lines are taken from the example of the transitions package, showing where to place the code for the transition

# escapades. Because the legal department says so.
self.machine.add_transition('complete_mission', 'saving the world', 'sweaty', 
                         after='update_journal')
def update_journal(self):
        """ Dear Diary, today I saved Mr. Whiskers. Again. """
        self.kittens_rescued += 1

However, how would I watch my queue, once i reached a state, in order to react to messages sent there that would should cause a transition from one state to another? From my basic knowledge, I would expect code in my state to wait for a message that could trigger the transition and call the transition to the following state.

I would have to create a thread inside the state machine, passing the state machine object as a argument in order to be able to trigger transitions.

Am I understanding this package correctly? Or am I using it wrongly?

like image 607
JoeyD Avatar asked Sep 28 '22 19:09

JoeyD


1 Answers

I would suggest doing it very differently. At the very least, it should be much easier to debug and maintain it according to this suggestion, in my opinion (explanation below).

  • First, your state machine code should not update the queues or listen to the queues directly. Instead it should just update some variable, like so:

    next_action = ''
    
    This is a transition
    def update_action(self, action):
        global next_action
        next_action = action
    

    (you should of course try to avoid global variables and work OO, but I'm simplifying as it's not the point of this answer).

  • Next you should have a queue and state-machine manipulator function, run by each of the threads:

    while some_condition:
         get the action from the queue
         update the state machine
         obtain the action from next_action
         push to the queue
    

Explanation - you should always separate your logic code from your system code. Writing a state machine that does not interact with queues, threads, etc., allows you to write code that is much easier to debug and test in unit tests. Only once the logic works, should you connect it to queues and such.

like image 105
Ami Tavory Avatar answered Oct 01 '22 07:10

Ami Tavory