Post on 16-Apr-2017
ruote - open source ruby workflow and bpm engine
Developed by John Mettrauxjmettraux.wordpress.com
Presented by Kenneth Kalmer in 20 minutesopensourcery.co.za
Workflows? BPM?
Improved state machine
Long running processes, long-lived process interpreter
Diverse participants
Complex rules & decisions
Implement clearly defined business processes
Joe's Mortgages
Applies on your behalf at seven different institutions
Selects the best deal for you
Handles application for you
You sign
You buy
You pay
State Machine
:requested
:evaluation
:acquired
:accepted
:applied
:approved
Where?
When?
Rate?
Comparison?
Who?
Rule: Notify Client when 4 quotes are received
aasm_state :pending_four_leftaasm_state :pending_three_leftaasm_state :pending_two_leftaasm_state :pending_one_leftaasm_state :pending_but_notified_client...aasm_state :is_this_ridiculous_or_what?
Rule: Wait up to 7 days for quotes
aasm_state :pending_four_remaining_timeoutaasm_state :pending_three_remaining_timoutaasm_state :pending_two_remaining_timoutaasm_state :pending_one_remaining_timoutaasm_state :call_recruiter_for_new_dev!
Recap
State machines are only valuable when they have a few, well defined states
Tempted to setup hundreds of states, with complex transitions
State machines help manage the results of real life processes, not the processes
Modified State Machine
class Mortgage aasm_initial_state :pending aasm_state :pending aasm_state :quoted aasm_state :applied aasm_state :approved aasm_state :rejectedend
Enter ruote
Clearly defined DSL for workflow
Clearly defined processesExpressions
Participants
Concurrent tasks
Timeouts
Easy decision making
Expressions
Utility statements that give structure to your processes
Conditional statements that facilitate branching and merging patterns
Participants
A point in the process where work gets done
Can be automated code
Can be human interaction
Ruote provides plenty of participants out the box
Breeze to write new ones
First round: Participants
class MortgageApplication < OpenWFE::ProcessDefinition sequence do institution_1 :activity => 'Mortgage Quote' institution_2 :activity => 'Mortgage Quote' institution_3 :activity => 'Mortgage Quote' institution_4 :activity => 'Mortgage Quote' institution_5 :activity => 'Mortgage Quote' institution_6 :activity => 'Mortgage Quote' institution_7 :activity => 'Mortgage Quote' endend
Problems so far
Will request quotations in serial
14 days to complete if each institution takes 2 days on average
Concurrency!
Not the Erlang kind, the business kind
Send all requests in one go, and continue the process once we've received at least 4 quotes
Also, quote process may not take longer than 7 days to complete
Second round: Concurrency and Timeout
class MortgageApplication < OpenWFE::ProcessDefinition sequence do timeout :after => '7d' do concurrence :count => 4 do institution_1 :activity => 'Mortgage Quote' institution_2 :activity => 'Mortgage Quote' institution_3 :activity => 'Mortgage Quote' institution_4 :activity => 'Mortgage Quote' institution_5 :activity => 'Mortgage Quote' institution_6 :activity => 'Mortgage Quote' institution_7 :activity => 'Mortgage Quote' end end endend
Achievements so far
Quotations requested simultaneously
Process will take 7 days at most to complete
First 4 institutions stand the chance of earning new business
Mortgage is still pending
Rule: Joe can re-request quotes
Joe drives a hard bargain
Can request quotes any number of times
But, wants to let the client know he's doing his best!
Third round: Bargain hard
class MortgageApplication < OpenWFE::ProcessDefinition sequence do loop do concurrence :timeout => '7d', :count => 4 do institution_1 :activity => 'Mortgage Quote' # ... end
joe :activity => 'Review quotes'
_break :if => ${f:joe_happy}
email :activity => Getting new quotes, :to => ${f:client.email} end endend
Achievements so far
Loop used to keep the quote request process running until Joe is happy, or cancels the process
Client notified everytime the quote request process starts all over again
First glimpse of workitems
Mortgage is still pending
Workitems?
The internal message passed from participant to participant
They're JSON friendly Ruby hashes
Participants can modify workitems
Processes can be launched with an initial payload, client details in this case, which is accessed through the workitems
Workitem attributes accessed in process definitions through the dollar notation
Quote found, action the client
class MortgageApplication < OpenWFE::ProcessDefinition sequence do loop do # ... end
secretary :activity => Send client application forms endend
Application received, apply at institution
class MortgageApplication < OpenWFE::ProcessDefinition sequence do # ...
secretary :activity => Send client application forms
participant :ref => ${f:selected_institution}, :activity => Apply for mortgage endend
Achievements so far
Dynamic participant specification from workitem attributes
Another human participant
Mortgage now in applied state
Let Joe Know
Joe reviews the results of the application, and notifies the client
Might attempt to restart the entire process
Joe has last say
class MortgageApplication < OpenWFE::ProcessDefinition sequence do # ...
participant :ref => ${f:selected_institution}, :activity => Apply for mortgage
joe :activity => Review application results endend
What happens here?
Joe will inform the client of the institutions response
Mortgage will stay in applied state, or move to approved/rejected states
Process ends
Possibilities from here
Automated decision makingDecision tables
Better conditional tests
Automated response processing, streamlines the feedback loop and decision making
Harass institutions that don't respond within 2 days of process timeout
Joe improves his handicap
Ruote & AASM
Great combination
Ruote handles business logic, AASM the state
AASM becomes skinny, ruote stays declarative
More ruote: Listeners
Start process, or wait forMessages from SQS
Jabber messages
Atom feed entries
More ruote: Cancel, cursors, replay & redo
When processes are cancelled, run sub-processes for cleanup tasks
Replay failed steps
Redo steps based on conditions
Jump to any point in the workflow using cursors
More ruote:
ruote-fluo
Graphical representation of process definitions
Edit process definitions on the fly
More ruote: Active*Participants
ActiveRecordParticipantSave workitem information in database
ActiveResourceParticipantInteract with any Rails resource as DHH intended you to do
Shameless Self Promotion
Developed the JabberParticipant and JabberListener now bundled with ruote
Added support for daemonizing ruote-rest
In talks on refactoring ruote-rest to become preferred Rails-friendly implementation of ruote
Summary
Process definitions built up from expressions
Expressions are steps in the workflow
Participants perform explicit function during workflow
Workitems used as internal messaging mechanism between expressions/participants
The best complement to any state machine implementation
Simplifies complex business process implementations
You have full control over the entire process
Thank You
opensourcery.co.za@kennethkalmer
openwferu.rubyforge.org#ruote on Freenodegroups.google.com/group/openwferu-users@jmettraux