Just released version 2.3.0 of ruote, a workflow engine for Ruby.
The last release was beginning March 2011, it was the 2.2.0. Many things happened, I couldn’t find the time to release a new version, although the developement was very active. Blame it on Bundler, it makes it so easy to just point at a master branch.
It could have been released as a 2.2.1 since there are no breaking changes, but I prefer to label it 2.3.0.
What’s new in this release, what’s improved? The changelog might be a bit dry. Here are some highlights:
-
Participants get a new callback: on_apply. It gives an opportunity to implementers to do something with the workitem before it gets dispatched to the (real) participant.
-
New flanking concept: parallel workflow lanes that get cancelled as soon as the sequence they belong to finishes.
-
Timers are like super timeouts. They list time deltas and what’s supposed to happen at that point.
-
Participants are given the opportunity to implement #rtimers and #rtimeout to specify their default timers/timeout. The process definition timers and the option timers take precedence.
-
Ruote::Dashboard preferred over Ruote::Engine. To emphasize that the engine is the whole dashboard(s) + worker(s) + storage system.
-
A template class for observing ruote events got added: Ruote::Observer. Hartog de Mik contributed a more refined version: Ruote::ProcessObserver. Implementations of these templates can be registered in ruote and log/observe/react on workflow activity.
-
etc…
Now some more detailed highlights:
participants
A 2.2.0 ruote participant would look like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Scout
include Ruote::LocalParticipant
def consume(workitem)
result = [ workitem.participant_name, (20 * rand + 1).to_i ]
workitem.fields['spotted'] << result
reply_to_engine(workitem)
end
def cancel(flavour)
# no need for a special implementation
end
end
Here is the 2.3.0 version. It favours “on_” methods, with implicit information (workitem, flavour, fei, …) Note that ruote 2.3.0 still accepts the above version.
1
2
3
4
5
6
7
8
9
10
11
12
class Scout < Ruote::Participant
def on_workitem
result = [ workitem.participant_name, (20 * rand + 1).to_i ]
workitem.fields['spotted'] << result
reply
end
# Ruote::Participant provides an empty default #on_cancel
end
radial
Until now, process definitions where mostly expressed in Ruby or in XML, or directly as (JSON) abstract trees.
There is a new mini-language called Radial available in the latest ruote. It aims for terseness, looks like a mix of JSON and Python (yes, significant indentation), and is not far from what it would look like in Ruby 1.9.
Radial:
1
2
3
4
5
6
define
concurrence merge_type: concat
scout_alice
scout_bob
scout_charly
leader_doug
Ruby 1.9:
1
2
3
4
5
6
7
8
Ruote.define do
concurrence merge_type: concat do
scout_alice
scout_bob
scout_charly
end
leader_doug
end
Radial is used as well in the “noisy” mode for debugging workflow activity, each time a workflow is launched, its radial version is displayed along with expression ids for easier activity deciphering.
The radial mini-language is parsed thanks to Parslet.
ruote-amqp rework
ruote-amqp needed some rework, it was too focused on queues for publishing whereas it should have been talking to exchanges. Hopefully the new version of ruote-amqp more closely follows the AMQP philosophy.
Note that Naoto Takai is working on a NATS pair of participant/listener (for ruote 2.2.x), it should work nicely with ruote 2.3.0. A valuable alternative to ruote-amqp.
There is ruote-stomp too, maintained by Kit Plummer.
storage implementations
Persistence is important for a workflow engine, some processes are expected to run for long times and survive engine failures and restarts. At the heart of ruote are storage implementations.
ruote-sequel
ruote-sequel is based on the powerful sequel tool. It persists workflows to relational databases (MySQL, PostgreSQL, and co).
To spare time, I decided to stop the developement of ruote-dm in favour of ruote-sequel. Ruote-sequel also benefitted from a recent rework in order to decrease the traffic between the worker(s) and the database (ruote is quite the query gun). Hopefully, as time flows and experience and feedback accumulate, workers and storage implementations get better.
ruote-mon
This new ruote-mon storage implementation is backed by MongoDB, it started out as ruote-mongodb under the lead of Nathan Stults. Ruote-mon is a rewrite that I personally maintain.
It’s currently quite the vanilla storage implementation. I hope to find some time to port some of the improvements in ruote-sequel to ruote-mon to decrease traffic between the worker(s) and MongoDB.
ruote-redis
ruote-redis slowly matured into 2.3.0. There were a few issues uncovered by various people. They are fixed by now.
ruote-swf
Unfortunately ruote-swf, backed by Amazon SWF is still behind a corporate wall. It’s an interesting implementation, it helped mature the worker and other storage implementations. It should be available by the end of the year.
other storage implementations
ruote-couch hasn’t made it to 2.3.0. I’d like to work on it, but since I have to make sure 2.3.0 reads couches written by 2.2.0, I’m a bit hesitant. I hope to find the time for an upgrade sprint (or two), I probably want a complete rewrite.
graphical process visualization (ruote-fluo)
ruote-fluo was rendering graphically process definitions to browser canvases. It had a few issues with big processes (memory leaks).
The new version leverages SVG (and CSS) instead, along with jQuery. I still have to implement a proper rendering for “if” expressions and then wrap it into ruote-kit.
remaining work
There are a few bugs reported by Chris Conley that have to be fixed (2.3.1 hopefully).
Marco Sehrer and other have reported inconsistencies with the StorageParticipant. They have to be addressed. Maybe the solution is a rework of the storage participant or a new participant (InboxParticipant?). I’d like to see that work in 2.3.1
ruote inside
Dan Ryan started the mastermind project, an infrastructure orchestration engine, full of ideas and energy.
links
- website
- mailing list
- IRC freenode.net #ruote
Many thanks for all the feedback and the contributions.
This release is dedicated to the memory of Claudio Petasecca-Donati, fellow developer, thanks for all your help.