Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

A simple workflow system using state machines

18,142 views

Published on

Outlines a simple workflow system using the acts_as_state_machine plugin for rails. Presented at Melbourne Ruby group 31/08/07.

Published in: Technology
  • on slide 12,
    eval('self.#{self.action}!')
    should be written as
    self.send('#{self.action}!'.to_sym)
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

A simple workflow system using state machines

  1. 1. A simple workflow system David Peterson peterson@orbitec.com.au
  2. 2. What is a workflow? A process that moves through a sequence of steps (from start and finish) in order to perform some function
  3. 3. Examples Fulfilling an order ● Publishing documents / content ● Approving a request ●
  4. 4. A few things in common ... Typically multi-step ● Performed asynchronously ● May be long-running ● Steps may be conditional ● Each step may need to do an operation ●
  5. 5. The Idea Many simple workflows can be modelled as a finite state machine (Not all)
  6. 6. acts_as_state_machine AASM to friends! ● Rails plugin by Scott Barron ● Provides: ● A simple FSM implementation ● A DSL for expressing FSM in Ruby code ●
  7. 7. http://elitists.textdriven.com/svn/plugins/ acts_as_state_machine/trunk/
  8. 8. # Basic workflow example class ActionWorkflow < ActiveRecord::Base acts_as_state_machine :initial => :created, :column => 'status' state :created state :approved state :rejected state :cancelled event :approve { transitions :to => :approved, :from => :created } event :cancel { transitions :to => :cancelled, :from =>[:created, :approved, :rejected] } ... end
  9. 9. AASM provides some methods An action! method for each event ● A query? method for each state ● Examples: workflow.approve! # moves to approved state workflow.cancelled? # Returns boolean
  10. 10. Guards event :approve { transitions :to => :approved, :from => :created, :guard => Proc.new {|w| !w.expired?}} Allows conditions on transitions ● Transition is not available unless ● condition is met Some conditions may be expressed ● best in your code, not in guards
  11. 11. Callbacks state :approved, :after => :on_submit state :approved, :after => :Proc.new {|m| m.abc } Available hooks :enter, :after and :exit ● Callbacks provide a way to do some ● operation when a transition occurs def on_submit record_action ... end
  12. 12. Other useful stuff # Fire your actions (cleanly) attr_accessor :action def action_workflow eval(quot;self.#{self.action}!quot;) unless self.action.nil? end # Add an audit trail ... has_many :actions, :class_name => quot;WorkflowActionquot; def record_action self.actions << WorkflowAction.create( :comment => self.comment, :actioner_id => self.acting_person, :state => self.state) end
  13. 13. A few caveats A minor change to AASM .rb required ● Avoids runtime error (on 1.2.3 anyway!) ● Also added a couple of things locally ● Lourens Naude's method (mis-named) ● A corrected next_events_for_current_state ● Ask me for the patch if you're keen ●
  14. 14. # Retrieves next states for current state def next_events_for_current_state events = [] self.class.read_inheritable_attribute( :transition_table).each do |key, value| value.each do |transition| events << key if transition.from == current_state() end end events end
  15. 15. Remarks AASM makes it very simple to implement a simple workflow model A full workflow system is more complex ● acts_as_coloured_petri_net :) ● Piston is your friend ... especially when ● making local modifications to plugins
  16. 16. Parting thought Q: What are the three most important ideas in programming? 1. Abstraction 2. Abstraction 3. Abstraction (Hudak, 2000)

×