<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>processi</title>
	<atom:link href="http://jmettraux.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://jmettraux.wordpress.com</link>
	<description>about processes and engines</description>
	<lastBuildDate>Fri, 16 Oct 2009 16:36:00 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='jmettraux.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/9bb51c7af8944bbbd925e4c759d5d471?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>processi</title>
		<link>http://jmettraux.wordpress.com</link>
	</image>
			<item>
		<title>Ruedas y Cervezas, first instance</title>
		<link>http://jmettraux.wordpress.com/2009/10/15/ruedas-y-cervezas-first-instance/</link>
		<comments>http://jmettraux.wordpress.com/2009/10/15/ruedas-y-cervezas-first-instance/#comments</comments>
		<pubDate>Thu, 15 Oct 2009 10:35:04 +0000</pubDate>
		<dc:creator>John Mettraux</dc:creator>
				<category><![CDATA[bpm]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruote]]></category>
		<category><![CDATA[workflow]]></category>

		<guid isPermaLink="false">http://jmettraux.wordpress.com/?p=1404</guid>
		<description><![CDATA[&#8220;ruote&#8221; is the Italian for &#8220;wheels&#8221;. It&#8217;s the name of our ruby workflow engine. The name was proposed by Tomaso Tosolini, it stuck and we liked how people pronounced it &#8220;route&#8221; which is a good fit for a tool that routes work among participants.
If you translate &#8220;ruote&#8221; to Spanish you get &#8220;ruedas&#8221;. Add a thirsty [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1404&subd=jmettraux&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://www.flickr.com/photos/popdakar/sets/72157622451585891/"><img src="http://farm3.static.flickr.com/2496/4007545729_5708d58701_m_d.jpg" style="border:0;" align="left" /></a>&#8220;ruote&#8221; is the Italian for &#8220;wheels&#8221;. It&#8217;s the name of our <a href="http://ruote.rubyforge.org">ruby workflow engine</a>. The name was proposed by Tomaso Tosolini, it stuck and we liked how people pronounced it &#8220;route&#8221; which is a good fit for a tool that routes work among participants.</p>
<p>If you translate &#8220;ruote&#8221; to Spanish you get &#8220;ruedas&#8221;. Add a thirsty community and you get <a href="http://groups.google.com/group/openwferu-users/t/22ed093d1d3df848">&#8220;ruedas y cervezas&#8221;</a>.</p>
<p>This event was organized and hosted by <a href="http://abstra.cc/">abstra.cc</a>, a madrilenian company doing wonders with Java, JRuby, Scala and their blend of agile magic.</p>
<p>The meeting was divided in three parts. First, abstra.cc presented their work with ruote. They&#8217;ve bound it <a href="http://www.flickr.com/photos/popdakar/4008298158/in/set-72157622451585891">into</a> their &#8220;Blue Mountain ERP&#8221; to drive the necessary business processes. Workitems are communicated to participants over XMPP. The platform is Java and the languages are <a href="http://jruby.org">JRuby</a> and <a href="http://www.scala-lang.org/">Scala</a>. As you might have guessed, they run ruote on JRuby.</p>
<p>Then, Iván Martínez, student in the <a href="http://upm.es">Universidad Politécnica de Madrid</a> <a href="http://www.flickr.com/photos/popdakar/4007532703/in/set-72157622451585891/">presented his work</a> on a <a href="http://groups.google.com/group/openwferu-users/browse_thread/thread/3e06ddfbd25e013f">graphical process editor for ruote</a>. It&#8217;s based on Flex and looks very promising. The abstra.cc guys encouraged him to share his code on <a href="http://github.com">github.com</a>, I hope he will follow this suggestion.</p>
<p>For the part when people really get thirsty, I cooked up a bunch of slides about ruote 2.0. They were presented by Nando Sola. I have embedded them here. The first half of them is about why ruote 2.0, while the latter half is about the enhancements to the ruote process definition language.</p>
<p>I felt it was necessary to communicate a bit about ruote 2.0, especially since, in Madrid, people have tremendously contributed to ruote 0.9 (many thanks guys !). Ruote 2.0 is a small jump from 0.9, literally a jump, not a step, explanations are required.</p>
<p>Then <a href="http://www.flickr.com/photos/popdakar/4007545729/in/set-72157622451585891/">beer ensued</a>. A ruedas y cervezas (rc2) is planned for next month, I wish I could attend. So if you&#8217;re in Madrid and you&#8217;re interested in ruote or, less narrowly, in Ruby / JRuby / Scala / Java, contact <a href="http://groups.google.com/group/openwferu-users/browse_thread/thread/22ed093d1d3df848">Nando Sola</a> and join the abstra.cc and UPM guys for the rc2.</p>
<p>&nbsp;</p>
<p><object type='application/x-shockwave-flash' wmode='transparent' data='http://static.slideshare.net/swf/ssplayer2.swf?id=2226153&#038;doc=towardsruote20-091015003740-phpapp02' width='700' height='574'><param name='movie' value='http://static.slideshare.net/swf/ssplayer2.swf?id=2226153&#038;doc=towardsruote20-091015003740-phpapp02' /><param name='allowFullScreen' value='true' /><param name='allowScriptAccess' value='always' /></object></p>
<p>&nbsp;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jmettraux.wordpress.com/1404/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jmettraux.wordpress.com/1404/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jmettraux.wordpress.com/1404/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jmettraux.wordpress.com/1404/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jmettraux.wordpress.com/1404/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jmettraux.wordpress.com/1404/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jmettraux.wordpress.com/1404/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jmettraux.wordpress.com/1404/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jmettraux.wordpress.com/1404/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jmettraux.wordpress.com/1404/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1404&subd=jmettraux&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://jmettraux.wordpress.com/2009/10/15/ruedas-y-cervezas-first-instance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8d96626e52beb1ff90f57a8e189e1e6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jmettraux</media:title>
		</media:content>

		<media:content url="http://farm3.static.flickr.com/2496/4007545729_5708d58701_m_d.jpg" medium="image" />
	</item>
		<item>
		<title>rufus-lua 1.1.0</title>
		<link>http://jmettraux.wordpress.com/2009/09/30/rufus-lua-1-1-0/</link>
		<comments>http://jmettraux.wordpress.com/2009/09/30/rufus-lua-1-1-0/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 05:04:16 +0000</pubDate>
		<dc:creator>John Mettraux</dc:creator>
				<category><![CDATA[lua]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rufus]]></category>

		<guid isPermaLink="false">http://jmettraux.wordpress.com/?p=1390</guid>
		<description><![CDATA[Just released rufus-lua 1.1.0. The original post I wrote about rufus-lua is named ruby to lua.
This release strongly benefited from Scott Persinger&#8217;s work on Laminate, a tool for safe user-authored templates for Vodpod.
Scott needed strong support for callbacks from Lua to Ruby and also ways to pass values back and forth. Many thanks to Scott [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1390&subd=jmettraux&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://lua.org"><img src="http://jmettraux.files.wordpress.com/2009/03/logo1.gif?w=128&#038;h=128" alt="lua" title="lua" width="128" height="128" class="alignleft size-full wp-image-1078" style="border:0;" /></a>Just released <a href="http://github.com/jmettraux/rufus-lua/">rufus-lua</a> 1.1.0. The original post I wrote about rufus-lua is named <a href="http://jmettraux.wordpress.com/2009/03/16/ruby-to-lua/">ruby to lua</a>.</p>
<p>This release strongly benefited from Scott Persinger&#8217;s work on <a href="http://github.com/scottpersinger/laminate">Laminate</a>, a tool for <a href="http://geekblog.vodpod.com/2009/09/10/laminate-safe-user-templates-for-ruby-apps/">safe user-authored templates</a> for Vodpod.</p>
<p>Scott needed strong support for callbacks from <a href="http://lua.org">Lua</a> to Ruby and also ways to pass values back and forth. Many thanks to Scott for the great collaboration.</p>
<p>Those of you interested in Lua and web applications should have a look at Norman Clarke&#8217;s <a href="http://github.com/norman/lua-haml">lua-haml</a> and at Daniele Alessandri&#8217;s <a href="http://github.com/nrk/mercury">mercury</a> (sinatra-like web framework for Lua).</p>
<p>&nbsp;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jmettraux.wordpress.com/1390/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jmettraux.wordpress.com/1390/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jmettraux.wordpress.com/1390/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jmettraux.wordpress.com/1390/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jmettraux.wordpress.com/1390/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jmettraux.wordpress.com/1390/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jmettraux.wordpress.com/1390/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jmettraux.wordpress.com/1390/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jmettraux.wordpress.com/1390/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jmettraux.wordpress.com/1390/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1390&subd=jmettraux&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://jmettraux.wordpress.com/2009/09/30/rufus-lua-1-1-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8d96626e52beb1ff90f57a8e189e1e6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jmettraux</media:title>
		</media:content>

		<media:content url="http://jmettraux.files.wordpress.com/2009/03/logo1.gif" medium="image">
			<media:title type="html">lua</media:title>
		</media:content>
	</item>
		<item>
		<title>rufus-tokyo 1.0.1</title>
		<link>http://jmettraux.wordpress.com/2009/09/18/rufus-tokyo-1-0-1/</link>
		<comments>http://jmettraux.wordpress.com/2009/09/18/rufus-tokyo-1-0-1/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 01:47:02 +0000</pubDate>
		<dc:creator>John Mettraux</dc:creator>
				<category><![CDATA[ffi]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rufus]]></category>
		<category><![CDATA[tokyocabinet]]></category>
		<category><![CDATA[tokyotyrant]]></category>

		<guid isPermaLink="false">http://jmettraux.wordpress.com/?p=1362</guid>
		<description><![CDATA[rufus-tokyo is a ruby-ffi based library for accessing Tokyo Cabinet and Tokyo Tyrant databases. It also feature a Rufus::Edo side where the native ruby/c extensions provided by the TC/TT author are used (for speed) instead of ruby-ffi.
rufus-tokyo contains ffi bindings for Tokyo Dystopia as well, thanks to Jeremy Hinegardner.
This is the changelog for this 1.0.1 [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1362&subd=jmettraux&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><img src="http://jmettraux.files.wordpress.com/2009/09/r0013818bb.jpg?w=150&#038;h=371" alt="yokohama cabinet" title="yokohama cabinet" width="150" height="371" class="alignleft size-full wp-image-1363" style="border:0;" /><a href="http://github.com/jmettraux/rufus-tokyo/">rufus-tokyo</a> is a ruby-ffi based library for accessing <a href="http://1978th.net/tokyocabinet/">Tokyo Cabinet</a> and Tokyo Tyrant databases. It also feature a Rufus::Edo side where the native ruby/c extensions provided by the TC/TT author are used (for speed) instead of ruby-ffi.</p>
<p>rufus-tokyo contains ffi bindings for <a href="http://1978th.net/tokyodystopia/">Tokyo Dystopia</a> as well, thanks to <a href="http://github.com/copiousfreetime/">Jeremy Hinegardner</a>.</p>
<p>This is the changelog for this 1.0.1 release :</p>
<pre>
== rufus-tokyo - 1.0.1    released 2009/09/18

- todo : add #putcat to Cabinet / Tyrant (Edo and Tokyo)
- todo : implemented search/union/intersection/difference for tables
- todo : added #putdup and #get4 to Cabinet / Tyrant (Edo and Tokyo)
- todo : better dylib 'detection' (Pietro Ferrari)
- todo : aliased lget to mget (thanks Runa)
- todo : proper Abort exception (Kenneth Kalmer)
</pre>
<p>&nbsp;</p>
<p><strong>putcat</strong> is used to append data to already stored value. getdup / <strong>get4</strong> is only relevant with b+ trees structures. They allow for multiple values stored under one key. This get4/getdup returns all the values stored under one key.</p>
<p>Since Tokyo Cabinet 1.4.29 (Tyrant 1.1.30), cabinet tables and tyrant tables have this new <strong>metasearch</strong> feature. This is what is meant by &#8220;search/union/intersection/difference&#8221; in the changelog.</p>
<p><a href="http://1978th.net/tech-en/promenade.cgi">Hirabayashi-san</a> is providing us with a way to combine queries. From rufus-tokyo, it looks like :</p>
<pre class="brush: ruby;">
require 'rubygems'
require 'rufus/tokyo' # sudo gem install rufus-tokyo

t = Rufus::Tokyo::Table.new('table.tct')

t['pk0'] = { 'name' =&gt; 'alfred', 'age' =&gt; '22', 'hobby' =&gt; 'fishing' }
t['pk1'] = { 'name' =&gt; 'bob', 'age' =&gt; '18', 'hobby' =&gt; 'hunting' }
t['pk2'] = { 'name' =&gt; 'charly', 'age' =&gt; '45', 'hobby' =&gt; 'fishing' }
t['pk3'] = { 'name' =&gt; 'doug', 'age' =&gt; '77', 'hobby' =&gt; 'fencing' }
t['pk4'] = { 'name' =&gt; 'ephrem', 'age' =&gt; '32', 'hobby' =&gt; 'swimming' }

rs = t.union(
  t.prepare_query { |q| q.add 'hobby', :equals, 'fishing' },
  t.prepare_query { |q| q.add 'age', :numgt, '20' }
)

rs.each { |r| p r }
  # ==&gt;
  # [&quot;pk2&quot;, {&quot;name&quot;=&gt;&quot;charly&quot;, &quot;hobby&quot;=&gt;&quot;fishing&quot;, &quot;age&quot;=&gt;&quot;45&quot;}]
  # [&quot;pk3&quot;, {&quot;name&quot;=&gt;&quot;doug&quot;, &quot;hobby&quot;=&gt;&quot;fencing&quot;, &quot;age&quot;=&gt;&quot;77&quot;}]
  # [&quot;pk4&quot;, {&quot;name&quot;=&gt;&quot;ephrem&quot;, &quot;hobby&quot;=&gt;&quot;swimming&quot;, &quot;age&quot;=&gt;&quot;32&quot;}]
  # [&quot;pk0&quot;, {&quot;name&quot;=&gt;&quot;alfred&quot;, &quot;hobby&quot;=&gt;&quot;fishing&quot;, &quot;age&quot;=&gt;&quot;22&quot;}]

t.close
</pre>
<p>This example returns the persons in the table who do fishing for a hobby OR whose age is greater than 20. The other methods understood by the table are intersection and difference.</p>
<p>For more information, see the <a href="http://github.com/jmettraux/rufus-tokyo/">rufus-tokyo source</a> on github and the <a href="http://rufus.rubyforge.org/rufus-tokyo/">rufus-tokyo rdoc</a>.</p>
<p>Many thanks to all the persons who contributed to rufus-tokyo.</p>
<p>&nbsp;</p>
<p>On the general Tokyo Cabinet / Tyrant front, <a href="http://github.com/actsasflinn">Flinn Mueller</a>, the author of <a href="http://github.com/actsasflinn/ruby-tokyotyrant">ruby-tokyotyrant</a> started a couple months ago a <a href="http://groups.google.com/group/tokyocabinet-users">mailing list</a> about Tokyo Cabinet / Tyrant. Lots of knowledge about the Tokyo products is exchanged there.</p>
<p>There is also the release of <a href="http://copiousfreetime.rubyforge.org/tyrantmanager/">tyrantmanager</a> by <a href="http://copiousfreetime.org/">Jeremy Hinegardner</a> (the author of the Dystopia bindings in rufus-tokyo). It&#8217;s a neat command line tool for managing Tokyo Tyrant instances, individually or in batch.</p>
<p>&nbsp;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jmettraux.wordpress.com/1362/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jmettraux.wordpress.com/1362/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jmettraux.wordpress.com/1362/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jmettraux.wordpress.com/1362/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jmettraux.wordpress.com/1362/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jmettraux.wordpress.com/1362/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jmettraux.wordpress.com/1362/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jmettraux.wordpress.com/1362/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jmettraux.wordpress.com/1362/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jmettraux.wordpress.com/1362/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1362&subd=jmettraux&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://jmettraux.wordpress.com/2009/09/18/rufus-tokyo-1-0-1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8d96626e52beb1ff90f57a8e189e1e6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jmettraux</media:title>
		</media:content>

		<media:content url="http://jmettraux.files.wordpress.com/2009/09/r0013818bb.jpg" medium="image">
			<media:title type="html">yokohama cabinet</media:title>
		</media:content>
	</item>
		<item>
		<title>Kenneth&#8217;s ruote talk</title>
		<link>http://jmettraux.wordpress.com/2009/08/27/kenneths-ruote-talk/</link>
		<comments>http://jmettraux.wordpress.com/2009/08/27/kenneths-ruote-talk/#comments</comments>
		<pubDate>Thu, 27 Aug 2009 06:04:09 +0000</pubDate>
		<dc:creator>John Mettraux</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruote]]></category>

		<guid isPermaLink="false">http://jmettraux.wordpress.com/?p=1348</guid>
		<description><![CDATA[Kenneth Kalmer uploaded his &#8220;ruote in twenty minutes&#8221; video.

I liked it a lot, an excellent mix of ruote idealism and south-african pragmatism.
It was 6 months ago though. We&#8217;re now working on ruote2.0, ruote-amqp, ruote-dm and the last addition is ruote-activerecord.
&#160;
       <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1348&subd=jmettraux&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://www.opensourcery.co.za">Kenneth Kalmer</a> uploaded his &#8220;ruote in twenty minutes&#8221; <a href="http://www.opensourcery.co.za/2009/08/25/ruote-in-20-minutes-video/">video</a>.</p>
<p><a href="http://www.opensourcery.co.za/2009/08/25/ruote-in-20-minutes-video/"><img src="http://jmettraux.files.wordpress.com/2009/08/kenneth.png?w=511&#038;h=386" alt="Kenneth Kalmer" title="Kenneth Kalmer" width="511" height="386" class="size-full wp-image-1349" style="border:0;" /></a></p>
<p>I liked it a lot, an excellent mix of ruote idealism and south-african pragmatism.</p>
<p>It was 6 months ago though. We&#8217;re now working on <a href="http://ruote.rubyforge.org">ruote2.0</a>, <a href="http://github.com/asm/ruote-amqp/">ruote-amqp</a>, <a href="http://github.com/jmettraux/ruote-dm/">ruote-dm</a> and the last addition is <a href="http://github.com/kennethkalmer/ruote-activerecord/">ruote-activerecord</a>.</p>
<p>&nbsp;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jmettraux.wordpress.com/1348/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jmettraux.wordpress.com/1348/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jmettraux.wordpress.com/1348/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jmettraux.wordpress.com/1348/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jmettraux.wordpress.com/1348/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jmettraux.wordpress.com/1348/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jmettraux.wordpress.com/1348/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jmettraux.wordpress.com/1348/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jmettraux.wordpress.com/1348/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jmettraux.wordpress.com/1348/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1348&subd=jmettraux&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://jmettraux.wordpress.com/2009/08/27/kenneths-ruote-talk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8d96626e52beb1ff90f57a8e189e1e6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jmettraux</media:title>
		</media:content>

		<media:content url="http://jmettraux.files.wordpress.com/2009/08/kenneth.png" medium="image">
			<media:title type="html">Kenneth Kalmer</media:title>
		</media:content>
	</item>
		<item>
		<title>edo cabinet &#8211; rubykaigi2009</title>
		<link>http://jmettraux.wordpress.com/2009/07/28/edo-cabinet-rubykaigi2009/</link>
		<comments>http://jmettraux.wordpress.com/2009/07/28/edo-cabinet-rubykaigi2009/#comments</comments>
		<pubDate>Tue, 28 Jul 2009 23:57:17 +0000</pubDate>
		<dc:creator>John Mettraux</dc:creator>
				<category><![CDATA[ffi]]></category>
		<category><![CDATA[lua]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rufus]]></category>
		<category><![CDATA[tokyocabinet]]></category>
		<category><![CDATA[tokyotyrant]]></category>

		<guid isPermaLink="false">http://jmettraux.wordpress.com/?p=1331</guid>
		<description><![CDATA[Here are my slides for the &#8220;edo cabinet&#8221; talk at the RubyKaigi2009.
I presented about Ruby-FFI, Tokyo Cabinet&#124;Tyrant and then rufus-tokyo and Rufus::Edo.
These are just slides, here is the english transcript of the actual talk.

&#160;
Many thanks to the RubyKaigi team for organizing this great event ! Special kudos to Leonard Chin for the on-the-fly translations, throughout [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1331&subd=jmettraux&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Here are my slides for the &#8220;edo cabinet&#8221; talk at the RubyKaigi2009.</p>
<p>I presented about <a href="http://kenai.com/projects/ruby-ffi">Ruby-FFI</a>, <a href="http://tokyocabinet.sourceforge.net/index.html">Tokyo Cabinet|Tyrant</a> and then <a href="http://github.com/jmettraux/rufus-tokyo/">rufus-tokyo</a> and Rufus::Edo.</p>
<p>These are just slides, here is the <a href="http://gist.github.com/157758">english transcript</a> of the actual talk.</p>
<p><object type='application/x-shockwave-flash' wmode='transparent' data='http://static.slideshare.net/swf/ssplayer2.swf?id=1742234&#038;doc=rkedocabinet-090719211107-phpapp02' width='700' height='574'><param name='movie' value='http://static.slideshare.net/swf/ssplayer2.swf?id=1742234&#038;doc=rkedocabinet-090719211107-phpapp02' /><param name='allowFullScreen' value='true' /><param name='allowScriptAccess' value='always' /></object></p>
<p>&nbsp;</p>
<p>Many thanks to the RubyKaigi team for organizing this great event ! Special kudos to <a href="http://blog.s21g.com/lchin">Leonard Chin</a> for the on-the-fly translations, throughout the 3 days.</p>
<p>You&#8217;ll find <a href="http://www.ustream.tv/channel/rubykaigi">videos of most of the talks</a> on ustream.tv (thanks to the KaigiFreaks) and most of the <a href="http://www.slideshare.net/event/rubykaigi2009">slides are available</a> from Slideshare.</p>
<p>&nbsp;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jmettraux.wordpress.com/1331/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jmettraux.wordpress.com/1331/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jmettraux.wordpress.com/1331/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jmettraux.wordpress.com/1331/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jmettraux.wordpress.com/1331/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jmettraux.wordpress.com/1331/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jmettraux.wordpress.com/1331/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jmettraux.wordpress.com/1331/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jmettraux.wordpress.com/1331/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jmettraux.wordpress.com/1331/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1331&subd=jmettraux&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://jmettraux.wordpress.com/2009/07/28/edo-cabinet-rubykaigi2009/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8d96626e52beb1ff90f57a8e189e1e6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jmettraux</media:title>
		</media:content>
	</item>
		<item>
		<title>rufus-tokyo 1.0.0</title>
		<link>http://jmettraux.wordpress.com/2009/07/23/rufus-tokyo-1-0-0/</link>
		<comments>http://jmettraux.wordpress.com/2009/07/23/rufus-tokyo-1-0-0/#comments</comments>
		<pubDate>Thu, 23 Jul 2009 01:24:32 +0000</pubDate>
		<dc:creator>John Mettraux</dc:creator>
				<category><![CDATA[jruby]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rufus]]></category>
		<category><![CDATA[tokyocabinet]]></category>
		<category><![CDATA[tokyotyrant]]></category>

		<guid isPermaLink="false">http://jmettraux.wordpress.com/?p=1308</guid>
		<description><![CDATA[Just released rufus-tokyo 1.0.0
This is mostly a &#8220;cleanup&#8221; release (spec reorg, to_s enforcement on key and values, and dropped backward compatibility with older TC/TT releases). Hence the 1.0.0.
There are new features though :
* Matthew King helped me add process method for table queries.
* Jeremy Hinegardner did an initial contribution on the front FFI / Tokyo [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1308&subd=jmettraux&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><img src="http://jmettraux.files.wordpress.com/2009/07/climax.jpg?w=257&#038;h=318" alt="climax" title="climax" width="257" height="318" class="alignright size-full wp-image-1311" style="border:0;" />Just released <a href="http://github.com/jmettraux/rufus-tokyo/">rufus-tokyo</a> 1.0.0</p>
<p>This is mostly a &#8220;cleanup&#8221; release (spec reorg, to_s enforcement on key and values, and dropped backward compatibility with older TC/TT releases). Hence the 1.0.0.</p>
<p>There are new features though :</p>
<p>* <a href="http://github.com/automatthew">Matthew King</a> helped me add <a href="http://github.com/jmettraux/rufus-tokyo/blob/73c467b3ec244efc0d913a4799057b4583267e7a/spec/shared_table_spec.rb#L337-419">process method</a> for table queries.</p>
<p>* <a href="http://www.copiousfreetime.org/">Jeremy Hinegardner</a> did an initial contribution on the front FFI / <a href="http://tokyocabinet.sourceforge.net/dystopiadoc/">Tokyo Dystopia</a>.</p>
<p>* <a href="http://github.com/therealadam/">Adam Keys</a> contributed the <a href="http://github.com/jmettraux/rufus-tokyo/blob/73c467b3ec244efc0d913a4799057b4583267e7a/spec/shared_table_spec.rb#L477-486">ext method</a> for the table structures (sorry, I had forgotten).</p>
<p>* full text search operators for table queries (:ftsphrase, :ftsec, :ftsor: ftsand) and the accompanying :token, :qgram and :opt inverted index types. I haven&#8217;t played <a href="http://github.com/jmettraux/rufus-tokyo/blob/73c467b3ec244efc0d913a4799057b4583267e7a/spec/table_spec.rb#L143-165">too</a> <a href="http://github.com/jmettraux/rufus-tokyo/blob/73c467b3ec244efc0d913a4799057b4583267e7a/spec/shared_table_spec.rb#L326-335">much</a> with them. Feedback is welcome.</p>
<p>For those of you interested in extending Tokyo Tyrant via Lua functions, I warmly recommend <a href="http://www.igvita.com/2009/07/13/extending-tokyo-cabinet-db-with-lua/">Ilya Grigork&#8217;s post</a> about it.</p>
<p>Many thanks to all the people who helped.</p>
<p>There will be a next release soon, as I&#8217;m busy trying to catch up with <a href="http://alpha.mixi.co.jp/blog/?author=3">Hirabayashi-san</a>.</p>
<p>rufus-tokyo : <a href="http://github.com/jmettraux/rufus-tokyo/">http://github.com/jmettraux/rufus-tokyo/</a></p>
<p>(picture graciously from <a href="http://twitter.com/michelledasilva">@michelledasilva</a>)</p>
<p>&nbsp;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jmettraux.wordpress.com/1308/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jmettraux.wordpress.com/1308/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jmettraux.wordpress.com/1308/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jmettraux.wordpress.com/1308/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jmettraux.wordpress.com/1308/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jmettraux.wordpress.com/1308/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jmettraux.wordpress.com/1308/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jmettraux.wordpress.com/1308/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jmettraux.wordpress.com/1308/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jmettraux.wordpress.com/1308/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1308&subd=jmettraux&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://jmettraux.wordpress.com/2009/07/23/rufus-tokyo-1-0-0/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8d96626e52beb1ff90f57a8e189e1e6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jmettraux</media:title>
		</media:content>

		<media:content url="http://jmettraux.files.wordpress.com/2009/07/climax.jpg" medium="image">
			<media:title type="html">climax</media:title>
		</media:content>
	</item>
		<item>
		<title>state machine != workflow engine</title>
		<link>http://jmettraux.wordpress.com/2009/07/03/state-machine-workflow-engine/</link>
		<comments>http://jmettraux.wordpress.com/2009/07/03/state-machine-workflow-engine/#comments</comments>
		<pubDate>Fri, 03 Jul 2009 14:48:04 +0000</pubDate>
		<dc:creator>John Mettraux</dc:creator>
				<category><![CDATA[openwferu]]></category>
		<category><![CDATA[rules]]></category>
		<category><![CDATA[ruote]]></category>
		<category><![CDATA[state machine]]></category>
		<category><![CDATA[workflow]]></category>

		<guid isPermaLink="false">http://jmettraux.wordpress.com/?p=1238</guid>
		<description><![CDATA[This post is intended for Ruby developers. The idea for it came after numerous discussions with fellow programmers about state machines and workflow engines. 
What motivates me for posting is the publication of the 3rd issue of the excellent Rails Magazine. It contains an article named &#8220;Workflow solutions with AASM&#8221;.
At first a word of warning, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1238&subd=jmettraux&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>This post is intended for Ruby developers. The idea for it came after numerous discussions with fellow programmers about state machines and workflow engines. </p>
<p>What motivates me for posting is the publication of the <a href="http://railsmagazine.com/issues/3">3rd issue</a> of the excellent Rails Magazine. It contains an article named &#8220;Workflow solutions with AASM&#8221;.</p>
<p>At first a word of warning, I wrote these lines with no intention of minimizing the potential of state machines vs workflow engines. I&#8217;m listing workflow engine and state machine implementations for Ruby at the end of this post.</p>
<p>There are a number of open questions in this post, I don&#8217;t intend to answer them now or later. There are so many different use cases in the wild.</p>
<p><strong>spark</strong></p>
<p>The article &#8220;Workflow solutions with AASM&#8221; starts with :</p>
<blockquote><p>
There are two main forms of workflows: sequential and<br />
state-machine. Sequential workflows are predictable. They<br />
utilize the rules and conditions we provide at the beginning<br />
to progress a process forward. The workflow is in control of<br />
the process.</p>
<p>A state-machine workflow is the reverse. It is driven by<br />
external events to its completion. We define the states and<br />
required transitions between those states. The workflow sits<br />
and waits for an external event to occur before transitioning<br />
to one of the defined states. The decision making process hap-<br />
pens externally outside of the workflow – there is a structure<br />
to be followed still like a sequential workflow but control is<br />
passed to its external environment.
</p></blockquote>
<p>I&#8217;m <a href="http://ruote.rubyforge.org">clearly</a> in the &#8220;sequential workflow&#8221; faction. But I refute the &#8217;sequential&#8217; label. Most of the state/transitions set out there can be qualified as &#8220;sequential&#8221;. Any workflow engine, in order to present any interest to its users, has to implement a certain number of <a href="http://workflowpatterns.com/patterns/control/index.php">[control flow] workflow patterns</a>. The number 1 control-flow pattern is named <a href="http://workflowpatterns.com/patterns/control/basic/wcp1.php">Sequence</a>, granted. But if you take a look at the pattern that immediately follows, it&#8217;s <a href="http://workflowpatterns.com/patterns/control/basic/wcp2.php">Parallel Split</a>. I can&#8217;t adhere to the &#8220;sequential workflow&#8221;  appellation.</p>
<p>Note that most workflow engines (you can call then &#8220;sequential workflow&#8221; engines) <a href="http://workflowpatterns.com/documentation/index.php">strive to implement</a> a large set of those control-flow patterns. This is usually done via their &#8216;process definition&#8217; language. The goal is to let users express their scenarii / pattern in a not too verbose way. We can argue that state machines may implement any of the control-flow patterns, my guess is &#8216;yes&#8217;, but what&#8217;s the cost in code ?</p>
<p>The difference between &#8220;sequential workflows&#8221; and &#8220;state machines&#8221; seems to lie not in the predictability of the former, but rather in how the flow between activities or state is weaved, especially how/where it&#8217;s concentrated.</p>
<p>Are &#8220;sequential workflows&#8221; and &#8220;state machines&#8221; excluding one another ?</p>
<p>The article states &#8220;sequential workflow are predictable. They utilize the rules and conditions we provide at the beginning&#8221;. It&#8217;s the same for state machines. The vast majority of [Ruby] state machine implementations rely on behaviour specified at implementation time (or right before the application&#8217;s [re]start).</p>
<p>The second paragraph I quoted up here says that &#8220;decision making process happens externally outside of the workflow (&#8230;) control is passed to its external environment&#8221;. I argue that a &#8220;sequential workflow&#8221; engine should do the same. A workflow [engine] can&#8217;t take a decision by itself, this task is usually handled by a human or a dedicated algorithm (a piece of code, a rule engine, a coin tossing engine wired to internet, whatever).</p>
<p><strong>case</strong></p>
<p>Wait, we&#8217;ve been using this &#8216;workflow&#8217; term quite liberally until now, what is it about ? Why do state machines seem to be the perfect vessel for it, at least in the eyes of the hard-working developer ?</p>
<p>Let&#8217;s look at how state machines are sold, at their use cases. Here is a classical example from a [Rails-oriented] state machine <a href="http://github.com/davidlee/state-fu/">library</a> :</p>
<pre class="brush: ruby;">
  class Document &lt; ActiveRecord::Base
    include StateFu

    def update_rss
      puts &quot;new feed!&quot;
      # ... do something here
    end

    machine( :status ) do
      state :draft do
        event :publish, :to =&gt; :published
      end

      state :published do
        on_entry :update_rss
        requires :author  # a database column
      end

      event :delete, :from =&gt; :ALL, :to =&gt; :deleted do
        execute :destroy
      end
    end
  end
</pre>
<p>It attaches behaviour (state and transitions) to a resource. If you look at the example of any Ruby state machine library out there, you will see this pattern : a set of states and transitions attached to a resource in the system (a Model).</p>
<p>Let&#8217;s move to an adjacent example, it&#8217;s also about a document, but it&#8217;s in the &#8220;sequential workflow&#8221; faction (<a href="http://ruote.rubyforge.org">ruote</a>). (The &#8216;cursor&#8217; expression in the process definition allows for the flow to be rewound or skipped&#8230;) :</p>
<pre class="brush: ruby;">
Ruote.process_definition :name =&gt; 'doc review', revision =&gt; '0.2' do

  cursor do

    participant '${f:author}', :step =&gt; 'finalize document'
    participant '${f:review_team}', :step =&gt; 'review document'

    rewind :unless =&gt; '${f:approved}'

    concurrence do
      participant '${f:publisher}', :step =&gt; 'publish document'
      participant '${f:author}', :step =&gt; 'publication notification'
    end
  end
end
</pre>
<p>There is a document yes, but it could be a folder of documents. The process definition is a separate thing, meant to be turned into multiple process instances.</p>
<p>Workflow engines are mostly process definitions interpreters, graduating as &#8220;operating systems for business processes&#8221; (think &#8216;ps&#8217; and &#8216;kill dash 9&#8242; but with business processes / process instances).</p>
<p>As said, most of the Ruby state machine libraries out there are all about binding behaviour to resources / models. What about moving to the workflow engine camp and instead of binding to a system artefact (document, order, invoice, book, customer, &#8230;) why not attach state and transitions to a virtual artefact, a so-called &#8220;process instance&#8221; ? The state machine would move out of its shell and turn into a full workflow engine. Or is that so ?</p>
<p><strong>cases</strong></p>
<p>Back to the 90% of the cases : the state machine attached to a model. What if there is more than 1 &#8220;stateable&#8221; model ? Easy. But what if transition in model A provokes a transition in model B ? The &#8220;real workflow&#8221; now lies at the intersection of two models.</p>
<p>The workflow engine will expose a process definition while, with the state machines, we&#8217;ll have to extract it from two or more models. Another advantage of workflow engines is that they have process definition versioning. Most of them run process instances from process definition X at version 2 happily with process instances from version 4, concurrently.</p>
<p>On the other hand, when a process instance goes ballistic it might take some time to repair it (align it with the reality of the business process). It might be easier with state machines, a simple SQL update usually, but what if there are multiple inter-related behaviours ? Pain on both sides.</p>
<p>Whatever the tool, you&#8217;ll have to carefully avoid locking yourself into your private hell of a system.</p>
<p><strong>nuances</strong></p>
<p>Kenneth Kalmer <a href="http://www.opensourcery.co.za/2009/07/06/driving-business-processes-in-ruby/">is using</a> a mix of <a href="http://github.com/pluginaweek/state_machine/">state_machine</a> and <a href="http://ruote.rubyforge.org">ruote</a> in their <a href="http://www.ispinabox.co.za/">ISP in a box</a> product. The state machine library is in charge of the state of its various models while the workflow engine does the orchestration. &#8220;Processes that drives the provision of services&#8221;</p>
<p>The two techniques may co-exist. Tinier states / transitions sets, more concise process definitions. Models managing their states, process instances coordinating the states of multiple models.</p>
<p>It&#8217;s OK to remove the workflow engine and replace it with a &#8220;super&#8221; state machine, but then you&#8217;re entering in the real workflow territory and the <a href="http://workflowpatterns.com">mindset</a> is a bit different and at that level, you&#8217;ll be exposed to a flavour of change that directly involves your customer / end-user. Nowhere to hide.</p>
<p><strong>machines</strong></p>
<p>I&#8217;ve been linking profusely to my <a href="http://ruote.rubyforge.org">ruote</a> workflow engine. The only other workflow engine I&#8217;ve spotted in the wild is <a href="http://rubyforge.org/projects/rbpm/">rbpm</a>, but its development stopped a long time ago.</p>
<p>Here is a non-exhaustive list of Ruby state machine implementations, in no specific order :</p>
<ul>
<li><a href="http://github.com/davidlee/state-fu/">state-fu</a></li>
<li><a href="http://github.com/pluginaweek/state_machine/">state_machine</a></li>
<li><a href="http://github.com/rubyist/aasm/tree/master">acts_as_state_machine</a></li>
<li><a href="http://github.com/ryan-allen/workflow/">ryan-allen&#8217;s workflow</a></li>
<li><a href="http://github.com/geekq/workflow/">geekq&#8217;s workflow</a> (fork of the previous)</li>
<li><a href="http://github.com/binary42/remix-machine/">remix-machine</a></li>
<li><a href="http://github.com/avdi/alter-ego/">alter-ego</a></li>
<li><a href="http://github.com/jbarnette/stateful/">stateful</a></li>
<li><a href="http://github.com/bokmann/stonepath/">stonepath</a> covered by an article in the <a href="http://www.pragprog.com/magazines/download/4.pdf">2009/10 pragprog magazine</a></li>
<li><a href="http://github.com/hashrocket/automatic-acts-as-state-machine/">automatic-acts-as-state-machine</a></li>
<li><a href="http://github.com/soveran/micromachine/">micromachine</a></li>
<li><a href="http://ruby-state-mach.rubyforge.org/">ruby-state-machine</a></li>
<li><a href="http://blog.envylabs.com/2009/08/the-rails-state-machine/">ActiveRecord::StateMachine</a> (announced)</li>
<li><a href="http://github.com/datamapper/dm-more/tree/master/dm-is-state_machine">dm-is-state_machine</a></li>
<li>&#8230;</li>
</ul>
<p>There&#8217;s a plethora of state machines versus very few (one or two) workflow engines. This could be interpreted in multiple ways.</p>
<p>State machines follow a well defined <a href="http://en.wikipedia.org/wiki/State_pattern">pattern</a>, while workflow engines have to follow a <a href="http://workflowpatterns.com">set of patterns</a>, and workflow engines strive to be &#8220;operating systems for business processes&#8221;. State machines are more humble.</p>
<p>So Rails Magazine #3 is <a href="http://railsmagazine.com/issues/3">out</a>. Great read.</p>
<p>&nbsp;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jmettraux.wordpress.com/1238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jmettraux.wordpress.com/1238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jmettraux.wordpress.com/1238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jmettraux.wordpress.com/1238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jmettraux.wordpress.com/1238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jmettraux.wordpress.com/1238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jmettraux.wordpress.com/1238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jmettraux.wordpress.com/1238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jmettraux.wordpress.com/1238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jmettraux.wordpress.com/1238/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1238&subd=jmettraux&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://jmettraux.wordpress.com/2009/07/03/state-machine-workflow-engine/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8d96626e52beb1ff90f57a8e189e1e6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jmettraux</media:title>
		</media:content>
	</item>
		<item>
		<title>rufus-tokyo 0.1.13</title>
		<link>http://jmettraux.wordpress.com/2009/06/02/rufus-tokyo-0-1-13/</link>
		<comments>http://jmettraux.wordpress.com/2009/06/02/rufus-tokyo-0-1-13/#comments</comments>
		<pubDate>Tue, 02 Jun 2009 00:47:40 +0000</pubDate>
		<dc:creator>John Mettraux</dc:creator>
				<category><![CDATA[ffi]]></category>
		<category><![CDATA[jruby]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rufus]]></category>
		<category><![CDATA[tokyocabinet]]></category>
		<category><![CDATA[tokyotyrant]]></category>

		<guid isPermaLink="false">http://jmettraux.wordpress.com/?p=1218</guid>
		<description><![CDATA[With the initial releases of rufus-tokyo, I happily cut corners and went with C strings (ending with NUL).
This isn&#8217;t optimal, often you need to store binary data as the value, the resulting &#8217;string&#8217; contains NUL characters and values get truncated at restitution. I was working around that with Base64 encoding. Fine, the perf cost isn&#8217;t [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1218&subd=jmettraux&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://www.flickr.com/photos/stevemettraux/3562217297"><img src="http://jmettraux.files.wordpress.com/2009/06/shinjuku.jpg?w=250&#038;h=178" alt="shinjuku" title="shinjuku" width="250" height="178" class="alignleft size-full wp-image-1223" style="border:0;" /></a>With the <a href="http://jmettraux.wordpress.com/2009/01/23/ruby-ffi-tokyo-cabinet/">initial releases</a> of rufus-tokyo, I happily cut corners and went with <a href="http://en.wikipedia.org/wiki/C_string">C strings</a> (ending with NUL).</p>
<p>This isn&#8217;t optimal, often you need to store binary data as the value, the resulting &#8217;string&#8217; contains NUL characters and values get truncated at restitution. I was working around that with Base64 encoding. Fine, the perf cost isn&#8217;t too heavy. But then, binary data was working fine on the Rufus::Edo side (wrapping the original tokyo{cabinet|tyrant}-ruby), why should Rufus::Tokyo be an exception ?</p>
<p>rufus-tokyo 0.1.13 which just got released fixes that issue.</p>
<p>Thanks to <a href="http://www.benmabey.com/">Ben Mabey</a> for pointing out the issue.</p>
<p><a href="http://blog.bitfluent.com/">Kamal Fariz Mahyuddin</a> was kind enough to fork rufus-tokyo and add the #putkeep(k, v) method which only put if there was no previous value associated with the key. The collaboration with Kamal also prompted me to provide #add_int and #add_double for int/double counters in cabinet/tyrant.</p>
<p><a href="http://github.com/jmettraux/rufus-tokyo">http://github.com/jmettraux/rufus-tokyo</a></p>
<p>&nbsp;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jmettraux.wordpress.com/1218/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jmettraux.wordpress.com/1218/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jmettraux.wordpress.com/1218/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jmettraux.wordpress.com/1218/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jmettraux.wordpress.com/1218/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jmettraux.wordpress.com/1218/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jmettraux.wordpress.com/1218/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jmettraux.wordpress.com/1218/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jmettraux.wordpress.com/1218/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jmettraux.wordpress.com/1218/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1218&subd=jmettraux&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://jmettraux.wordpress.com/2009/06/02/rufus-tokyo-0-1-13/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8d96626e52beb1ff90f57a8e189e1e6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jmettraux</media:title>
		</media:content>

		<media:content url="http://jmettraux.files.wordpress.com/2009/06/shinjuku.jpg" medium="image">
			<media:title type="html">shinjuku</media:title>
		</media:content>
	</item>
		<item>
		<title>rufus-scheduler 2.0, with em flavour</title>
		<link>http://jmettraux.wordpress.com/2009/05/07/rufus-scheduler-20-with-em-flavour/</link>
		<comments>http://jmettraux.wordpress.com/2009/05/07/rufus-scheduler-20-with-em-flavour/#comments</comments>
		<pubDate>Thu, 07 May 2009 02:27:36 +0000</pubDate>
		<dc:creator>John Mettraux</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[rufus]]></category>
		<category><![CDATA[scheduling]]></category>

		<guid isPermaLink="false">http://jmettraux.wordpress.com/?p=1194</guid>
		<description><![CDATA[This blog is turning into a release gallery.
Anyway. Just released rufus-scheduler 2.0. It&#8217;s a complete rewrite. The only new &#8220;feature&#8221; is an EventMachine mode.
The plain scheduler uses a thread waking up every 0.330s (by default) to check for jobs to trigger, while the em-based scheduler uses an EventMachine timer.
Other flavour for the core loop are [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1194&subd=jmettraux&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://github.com/jmettraux/rufus-scheduler/"><img src="http://jmettraux.files.wordpress.com/2009/05/jlc1.png?w=150&#038;h=225" title="swiss made" width="150" height="225" border="0" class="alignleft size-full wp-image-1196" style="border:0;padding-right:5px;"></a>This blog is turning into a release gallery.</p>
<p>Anyway. Just released <a href="http://github.com/jmettraux/rufus-scheduler/">rufus-scheduler</a> 2.0. It&#8217;s a complete rewrite. The only new &#8220;feature&#8221; is an <a href="http://www.rubyeventmachine.com/">EventMachine</a> mode.</p>
<p>The plain scheduler uses a thread waking up every 0.330s (by default) to check for jobs to trigger, while the em-based scheduler uses an EventMachine timer.</p>
<p>Other flavour for the core loop are possible, why not something 1.9 fiber based in the short term ?</p>
<p>This release 2.0 is mostly backward compatible. Only some corner cases and advanced usages (block arity) have changed (they have been simplified). Having a look at the <a href="http://github.com/jmettraux/rufus-scheduler/blob/master/README.rdoc">readme</a> should help.</p>
<pre class="brush: ruby;">
require 'rubygems'
require 'rufus/scheduler' # sudo gem install rufus-scheduler

s = Rufus::Scheduler.start_new
</pre>
<p>will still work, it will return an instance of Rufus::Scheduler::PlainScheduler, but if an EM reactor is running, it will stick to it and return a Rufus::Scheduler::EmScheduler instance.</p>
<p>source : <a href="http://github.com/jmettraux/rufus-scheduler/">http://github.com/jmettraux/rufus-scheduler/</a><br />
rdoc : <a href="http://rufus.rubyforge.org/rufus-scheduler/">http://rufus.rubyforge.org/rufus-scheduler/</a><br />
ml : <a href="http://groups.google.com/group/rufus-ruby">http://groups.google.com/group/rufus-ruby</a></p>
<p>Many thanks to <a href="http://github.com/kjwierenga">Klaas Jan Wierenga</a> for contributing nice stress tests (for the 1.0 and the 2.0 branches), thanks as well to <a href="http://github.com/kennethkalmer">Kenneth Kalmer</a> for its <a href="http://www.opensourcery.co.za/2009/04/28/easy-ruby-cronjobs-with-daemon-kit/">daemon-kit + rufus-scheduler</a> effort.</p>
<p>&nbsp;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jmettraux.wordpress.com/1194/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jmettraux.wordpress.com/1194/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jmettraux.wordpress.com/1194/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jmettraux.wordpress.com/1194/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jmettraux.wordpress.com/1194/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jmettraux.wordpress.com/1194/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jmettraux.wordpress.com/1194/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jmettraux.wordpress.com/1194/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jmettraux.wordpress.com/1194/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jmettraux.wordpress.com/1194/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1194&subd=jmettraux&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://jmettraux.wordpress.com/2009/05/07/rufus-scheduler-20-with-em-flavour/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8d96626e52beb1ff90f57a8e189e1e6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jmettraux</media:title>
		</media:content>

		<media:content url="http://jmettraux.files.wordpress.com/2009/05/jlc1.png" medium="image">
			<media:title type="html">swiss made</media:title>
		</media:content>
	</item>
		<item>
		<title>rufus-decision 1.1, ruby decision tables</title>
		<link>http://jmettraux.wordpress.com/2009/04/25/rufus-decision-11-ruby-decision-tables/</link>
		<comments>http://jmettraux.wordpress.com/2009/04/25/rufus-decision-11-ruby-decision-tables/#comments</comments>
		<pubDate>Sat, 25 Apr 2009 14:19:50 +0000</pubDate>
		<dc:creator>John Mettraux</dc:creator>
				<category><![CDATA[decision]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rufus]]></category>
		<category><![CDATA[rules]]></category>

		<guid isPermaLink="false">http://jmettraux.wordpress.com/?p=1136</guid>
		<description><![CDATA[rufus-decision is a small ruby gem for &#8216;running decision tables&#8217;. Decision tables are useful for mapping conditions to actions.
This example decision table considers two conditions : &#8216;topic&#8217; and &#8216;region&#8217; (I tend to call them &#8216;inputs&#8217;). Certain combinations of condition  yield one or more output value.
In the example, when the topic is about finance and [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1136&subd=jmettraux&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://github.com/jmettraux/rufus-decision/">rufus-decision</a> is a small ruby gem for &#8216;running decision tables&#8217;. <a href="http://en.wikipedia.org/wiki/Decision_table">Decision tables</a> are useful for mapping conditions to actions.</p>
<p><img src="http://jmettraux.files.wordpress.com/2009/04/decision_table_0.png?w=263&#038;h=180" alt="which reporter for which event" title="decision_table_0" width="263" height="180" class="size-full wp-image-1141" style="border:0;" align="left" />This example decision table considers two conditions : &#8216;topic&#8217; and &#8216;region&#8217; (I tend to call them &#8216;inputs&#8217;). Certain combinations of condition  yield one or more output value.</p>
<p>In the example, when the topic is about finance and the region is Europe, the team member Donald gets selected.</p>
<p>This is a vanilla decision table, as soon as a &#8216;match&#8217; is found, the run is over, an output value has been found.</p>
<p>Note that the arrangement of rules, their order, does matter. Ernest who is in charge of finance for the rest of the world, comes after America and Europe, Charly and Donald respectively. If Ernest were placed before them, all the input sets with the topic set to &#8216;finance&#8217; would go to him, ignoring his two colleagues.</p>
<p>Likewise, our &#8216;handle all the rest&#8217; Zach has been placed last, collecting all the input sets that didn&#8217;t match.</p>
<p>It&#8217;s easy to reproduce the table with some code :</p>
<pre class="brush: ruby;">
if topic == 'sports'
  if region == 'europe'
    team_member = 'Alice'
  else
    team_member = 'Bob'
  end
elsif topic == 'finance'
  # ...
elsif topic == 'politics'
  # ...
else
  team_member = 'Zach'
end
</pre>
<p>Turning business logic into code is a common task for software developers, but what about simply &#8216;running&#8217; a decision table directly ?</p>
<p>Decision tables are easy to edit with spreadsheet software and that&#8217;s a happy coincidence since many domain experts are Excel jockeys (see <a href="http://martinfowler.com/bliki/LayProgrammer.html">lay programmer</a>).</p>
<p>Excel isn&#8217;t the only spreadsheet software, see for example our decision table in <a href="http://spreadsheets.google.com/pub?key=rs4Z_1gjtyfgXupxXz_nAYw">Google Spreadsheet</a>.</p>
<p>At this point, I have to say I&#8217;m sorry, I won&#8217;t suggest any mean to run decision tables directly inside of Excel, I will bring back the flow to the Ruby environment, with some code triggering our business logic.</p>
<pre class="brush: ruby;">
require 'rubygems'
require 'rufus/decision' # sudo gem install rufus-decision

table = %{
  in:topic,in:region,out:team_member
  sports,europe,Alice
  sports,,Bob
  finance,america,Charly
  finance,europe,Donald
  finance,,Ernest
  politics,asia,Fujio
  politics,america,Gilbert
  politics,,Henry
  ,,Zach
}

table = Rufus::Decision::Table.new(table)

p table.run('topic' =&gt; 'politics', 'region' =&gt; 'america')
  # =&gt; {&quot;region&quot;=&gt;&quot;america&quot;, &quot;topic&quot;=&gt;&quot;politics&quot;, &quot;team_member&quot;=&gt;&quot;Gilbert&quot;}

p table.run('topic' =&gt; 'sports', 'region' =&gt; 'antarctic')
  # =&gt; {&quot;region&quot;=&gt;&quot;antarctic&quot;, &quot;topic&quot;=&gt;&quot;sports&quot;, &quot;team_member&quot;=&gt;&quot;Bob&quot;}

p table.run('topic' =&gt; 'culture', 'region' =&gt; 'america')
  # =&gt; {&quot;region&quot;=&gt;&quot;america&quot;, &quot;topic&quot;=&gt;&quot;culture&quot;, &quot;team_member&quot;=&gt;&quot;Zach&quot;}
</pre>
<p>rufus-decision understands decision tables with rules expressed per column as well as per row :</p>
<pre class="brush: ruby;">
table = %{
  in:topic,sports,sports,finance,finance,finance,politics,politics,politics,
  in:region,europe,,america,europe,,asia,america,,
  out:team_member,Alice,Bob,Charly,Donald,Ernest,Fujio,Gilbert,Henry,Zach
}
</pre>
<p>The parameter to Rufus::Decision::Table.new() can be a CSV string, an array of arrays, the path to a CSV file or the URI of a CSV file. With a Google spreadsheet [published] table, our example could be cut to :</p>
<pre class="brush: ruby;">
require 'rubygems'
require 'rufus/decision' # sudo gem install rufus-decision

table = Rufus::Decision::Table.new(
  'http://spreadsheets.google.com/pub?key=rs4Z_1gjtyfgXupxXz_nAYw&amp;output=csv')

# ...
</pre>
<p>So far so good, our domain expert may publish decision tables on the company information&#8217;s system and we can use them directly. But what to do when the number of conditions and rules get large ?</p>
<p>A programmer is expected to test his code, he&#8217;s even expected to deliver code with tests. A sane programmer can&#8217;t live without tests. Lay programmers should welcome testing as well.</p>
<p>rufus-decision comes with a &#8220;rufus_decide&#8221; command line tool for running decision tables in batch.</p>
<p>Given this input file (topics_in.csv), where the first row lists the keys and the next rows hold the values :</p>
<pre style="margin-left:1em;margin-bottom:1em;">
topic,region
sports,america
politics,europe
culture,
politics,africa
</pre>
<p>the decision table can be exercised with :</p>
<pre style="margin-left:1em;margin-bottom:1em;">
rufus_decide \
-t "http://spreadsheets.google.com/pub?key=rs4Z_1gjtyfgXupxXz_nAYw&amp;output=csv" \
-i topics_in.csv
</pre>
<p>which will yield :</p>
<pre style="margin-left:1em;margin-bottom:1em;">
region,team_member,topic
america,Bob,sports
europe,Henry,politics
,Zach,culture
africa,Henry,politics
</pre>
<p>&#8216;rufus_decide&#8217; ran the decision table for each row in the input data and generated an output table with one row for each input row.</p>
<p>This &#8216;ideal&#8217; output can saved in a &#8216;goal.csv&#8217; file and used to &#8216;test&#8217; the decision table :</p>
<pre style="margin-left:1em;margin-bottom:1em;">
rufus_decide \
-t "http://spreadsheets.google.com/pub?key=rs4Z_1gjtyfgXupxXz_nAYw&amp;output=csv" \
-i topics_in.csv \
-g goal.csv
</pre>
<p>Running rufus_decide with a goal will emit an output similar to the one of classical unit test tools.</p>
<p>This was an introduction to rufus-decision, whose version 1.1.0 was just released.</p>
<p><a href="http://jmettraux.files.wordpress.com/2009/04/web_decision.png"><img src="http://jmettraux.files.wordpress.com/2009/04/web_decision.png?w=150&#038;h=85" alt="web_decision" title="web_decision" width="150" height="85" class="alignleft size-thumbnail wp-image-1189" style="border:0;" /></a>The new release contains some kind of web-based <a href="http://github.com/jmettraux/rufus-decision/tree/master/demo">environment</a> for testing rules (see thumbnail on left), but well, I&#8217;m not quite convinced it&#8217;s useful.</p>
<p>source : <a href="http://github.com/jmettraux/rufus-decision/">http://github.com/jmettraux/rufus-decision/</a><br />
rdoc : <a href="http://rufus.rubyforge.org/rufus-decision/">http://rufus.rubyforge.org/rufus-decision/</a></p>
<p>&nbsp;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jmettraux.wordpress.com/1136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jmettraux.wordpress.com/1136/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jmettraux.wordpress.com/1136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jmettraux.wordpress.com/1136/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jmettraux.wordpress.com/1136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jmettraux.wordpress.com/1136/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jmettraux.wordpress.com/1136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jmettraux.wordpress.com/1136/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jmettraux.wordpress.com/1136/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jmettraux.wordpress.com/1136/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=jmettraux.wordpress.com&blog=120793&post=1136&subd=jmettraux&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://jmettraux.wordpress.com/2009/04/25/rufus-decision-11-ruby-decision-tables/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8d96626e52beb1ff90f57a8e189e1e6f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">jmettraux</media:title>
		</media:content>

		<media:content url="http://jmettraux.files.wordpress.com/2009/04/decision_table_0.png" medium="image">
			<media:title type="html">decision_table_0</media:title>
		</media:content>

		<media:content url="http://jmettraux.files.wordpress.com/2009/04/web_decision.png?w=150" medium="image">
			<media:title type="html">web_decision</media:title>
		</media:content>
	</item>
	</channel>
</rss>