Ruote is a workflow engine written in Ruby. Ruote is not a state machine library.
Last version is 2.3.0, it was released 2012/09/04.
Here is a re-hash of the quickstart exposing the core concepts in ruote.
Ruote as a workflow engine comes as an “onion”. There’s a storage at the core, taking care of all the persistence. A worker where all the orchestration work happens surrounds the core. The dashboard has all the levers to launch, pause, cancel process instances.
require 'rufus-json/automatic'
require 'ruote'
require 'ruote/storage/fs_storage'
ruote = Ruote::Dashboard.new(
Ruote::Worker.new(
Ruote::FsStorage.new('ruote_work')))
The orchestration work (making the work flow) happens in the worker(s), the orchestrated work (where the added value is) happens in participants.
class Scout < Ruote::Participant
def on_workitem
sleep(rand)
result =
[ workitem.participant_name, (20 * rand + 1).to_i ]
(workitem.fields['spotted'] ||= []) << result
p result
reply # work done, let flow resume
end
end
class Leader < Ruote::Participant
def on_workitem
workitem.fields['total'] =
workitem.fields['spotted'].inject(0) { |t, f| t + f[1] }
puts
puts "bird: " + workitem.fields['bird']
puts "spotted: " + workitem.fields['spotted'].inspect
puts "total: " + workitem.fields['total'].inspect
puts
reply # work done, let flow resume
end
end
Participant names are mapped to participant implementations via a register call.
ruote.register /^scout_/, Scout
ruote.register /^leader_/, Leader
A process definition can be expressed in radial (a mini-language specific to ruote), in Ruby, in XML or directly as a (JSON) abstract tree.
Here is a radial example:
pdef = %q{
define
concurrence merge_type: concat
scout_alice
scout_bob
scout_charly
leader_doug
}
This process definition fans work to three scout participants and then hands the resulting work (item) to the team leader.
Here is the same flow expressed in Ruby:
pdef = Ruote.define do
concurrence :merge_type => :concat do
scout_alice
scout_bob
scout_charly
end
leader_doug
end
Multiple process instances can be launched at the same time. Multiple instances of different processes with different initial workitem fields can be launched in the same system and run in parallel, much like different processes on top of an OS.
wfid = ruote.launch(
pdef,
'bird' => %w[ thrush cardinal dodo ].shuffle.first)
Ruote is available under the MIT open source license.
Ruote used to be named ‘openwfe-ruby’ then ‘openwferu’. The name is now ‘ruote’ (pronounce it ‘ru-o-te’ or ‘route’, as you wish).
For more, head to the documentation or to the quickstart or have a look at a few slides.
community
The mailing list is still the ‘openwferu’ one at http://groups.google.com/group/openwferu-users
The freenode.net channel is #ruote, feel free to stop by for a chat and a coffee. The channel archives are available at http://ruote-irclogs.s3.amazonaws.com/logs.html
See source for a list of the ruote related projects on github.
Here is a non-exhaustive list of organizations using ruote.