Recently I am being assigned to work on a FSM based workflow system to enable my other colleagues to use it in their application. I am rather impressed with the simplicity of the workflow system (initially designed by my Technical Director) and decided to post some notes here. The workflow system was developed for CodeIgniter PHP framework and Drupal CMS.
What is FSM?
FSM, or Finite State Machine, as quoted from my good old lecture notes, is as follows:
A machine is a device which accepts some inputs, possibly produces some output, and has some memory sorting information on the overall results of all previous inputs.
The condition of the machine at a particular instance is called a state of the machine. New input changes the state, may be to another state, and may be to the same state. The effect of a new input depends on the present state the machine is in.
…If the total number of possible states is finite, the machine is called finite state machine, eg. a computer.
Because I find it easy to implement. In a work flowed application, for example a form processing system. Each form submitted has a state. After being reviewed by the supervisor (for example), then the state changes. With FSM, we can predict the next state of the record because it has to follow the state transition function defined.
What about Access Control? What if the user tries to mess up the system?
Because the system was designed to work together with Drupal CMS, therefore we uses whatever Drupal is able to deliver to us. We have setup a couple of roles so that a user can be assigned to a number of roles. Then we define in our state transition table what role the user must play in order to perform the transition. Besides that, we also defined access control to the record in each state – only user playing one of the certain roles can read the record in specific state.
Let’s say we have a FSM that models a simple Article Publshing System as follows:-
For simplicity’s sake we do not touch on access control here. As shown on the diagram (which is generated by graphviz), this is a simple publishing system that shows a life-cycle of an article. Probably there should be more details (more states, more transitions) to be in but adding them in would make this article out of scope. You would probably notice that this does not look like a finite state machine that you see in your Discrete Mathematics textbook but we talk about this some other day.
Alright, the diagram should be self-explanatory enough. Each directed path/edge (arrowed lines) shows the transition flow from one state to another but not in reverse direction, i.e. an article in Draft state is not allowed to go back to NEW state. Next we see how are we going to represent the FSM in our database. First we need the record row,
posts (post_id, title, content, state_id *)
where the state_id references the post_states below,
post_states (state_id, name, description)
Followed by possible transitions:
post_transitions (transition_id, name, description, from_state *, to_state *)
Before updating record in posts table, we should first check whether the transition is possible. Hence we need to gather two pieces of information before updating the record in the posts table. First is the post’s state_id, second is the transition name. If there is a record returned from post_transitions, we can obtain the next state_id of the post by referring to the to_state field. Otherwise the transition is invalid and should be canceled.
Easy to understand, easy to maintain.
Basically what we are doing right now is that we define the states and transition in a YAML configuration file. Then my work flow library will generate the corresponding SQL, dot file to be used to generate FSM diagram (as you can see above) and flowchart (yes, the flowchart). Hence the main disadvantage with this approach is that changes must be handled carefully. Otherwise if you are not using an automated tool to maintain the FSM model in database, it shouldn’t cause much trouble.
Having a FSM based workflow system can greatly reduce the time taken to model and develop a workflowed system. What’s more exciting is that with this FSM based workflow system we can use this to as a base for history logging system. Unfortunately I have still doing some research in implementing the history logging system. However I found this article on history table posted by Downs on reddit yesterday and it definitely helps if you want to go on further.
You may be interested in the actual code but I do not think I am allowed to post the code. Anyway I am going to rewrite the workflow system to be used in my personal project which will be built with Zend Framework. However, I don’t think I will be offering the exactly same feature set that I develop for my company as I do not require all of them :P. After having the component written, I would post it online so that you can see how it is being implemented.