Skip to content

How to Use the Workflow

Mostafa Barmshory edited this page Feb 22, 2017 · 2 revisions

State machine cannot be in more than one place simultaneously. It is also worth noting that a workflow does not commonly have cyclic path in the definition graph, but it is common for a state machine.

Example of a State Machine

An example of a mechanism that can be modeled by a state machine is a turnstile. A turnstile, used to control access to subways and amusement park rides, is a gate with three rotating arms at waist height, one across the entryway. Initially the arms are locked, blocking the entry, preventing patrons from passing through. Depositing a coin or token in a slot on the turnstile unlocks the arms, allowing a single customer to push through. After the customer passes through, the arms are locked again until another coin is inserted.

Considered as a state machine, the turnstile has two possible states: Locked and Unlocked. There are two possible inputs that affect its state: putting a coin in the slot (coin) and pushing the arm (push). In the locked state, pushing on the arm has no effect; no matter how many times the input push is given, it stays in the locked state. Putting a coin in – that is, giving the machine a coin input – shifts the state from Locked to Unlocked. In the unlocked state, putting additional coins in has no effect; that is, giving additional coin inputs does not change the state. However, a customer pushing through the arms, giving a push input, shifts the state back to Locked.

state machine

The turnstile state machine can be represented by a state transition table, showing for each possible state, the transitions between them (based upon the inputs given to the machine) and the outputs resulting from each input:

Others are invalided and throw exceptions.

Data model is:

Class Example_Turnstile extends Pluf_Model {
    function init()
    {
        $this->_a['table'] = 'turnstile';
        $this->_a['verbose'] = 'turnstile';
        $this->_a['cols'] = array(
                'id' => array(
                        'type' => 'Pluf_DB_Field_Sequence',
                        'blank' => true,
                        'readable' => true,
                        'editable' => false
                ),
                'name' => array(
                        'type' => 'Pluf_DB_Field_Varchar',
                        'blank' => false,
                        'size' => 50,
                        'verbose' =>'name',
                        'readable' => true,
                        'editable' => true
                ),
                'state' => array(
                        'type' => 'Pluf_DB_Field_Varchar',
                        'blank' => true,
                        'size' => 20,
                        'verbose' => 'description',
                        'readable' => true,
                        'editable' => true
                )
        );
}

Below is the configuration for the request state machine.

$states =  array(
        'Unlocked' => array(
                // Transaction or event
                'push' => array(
                        'next' => 'Locked',
                        'action' => array(
                                'Example_View',
                                'openGate'
                        )
                )
        ),
        'Locked' => array(
                'coin' => array(
                        'next' => 'Unlocked',
                        'action' => array(
                                'Example_View',
                                'getCoin'
                        )
                )
        )
);

Here is a simple usage:

$object = new Example_Turnstile(); 
$machine = new Pluf_StateMachine();
$machine
    ->setStates($states)
    ->setProperty('state')
    ->transact($request, $object, $transaction);
Current State Input Next State Output
Locked coin Unlocked Unlocks the turnstile so that the customer can push through.
Unlocked push Locked When the customer has pushed through, locks the turnstile.
Clone this wiki locally