From 53780de6290554435ea7f140aabb4c7141f8b3bd Mon Sep 17 00:00:00 2001 From: John Mettraux Date: Thu, 20 Dec 2012 09:46:18 +0900 Subject: [PATCH] ready for release --- _layouts/post.html | 2 +- ...012-12-14-ruote-and-the-await-attribute.md | 77 +++++++++++++------ css/style.css | 2 + 3 files changed, 55 insertions(+), 26 deletions(-) diff --git a/_layouts/post.html b/_layouts/post.html index 483e06c..ef972b2 100644 --- a/_layouts/post.html +++ b/_layouts/post.html @@ -19,7 +19,7 @@

{{ page.title }} {{ content }}
- © 2011-2012 John Mettraux + © 2011-2013 John Mettraux
diff --git a/_posts/2012-12-14-ruote-and-the-await-attribute.md b/_posts/2012-12-14-ruote-and-the-await-attribute.md index c6db25e..f6b9b1a 100644 --- a/_posts/2012-12-14-ruote-and-the-await-attribute.md +++ b/_posts/2012-12-14-ruote-and-the-await-attribute.md @@ -4,11 +4,11 @@ title: ruote and the :await attribute --- _tl;dr_
-ruote has got a new "await" attribute (can be placed on any expression) that suspends the application of the expression until a condition (entering or leaving a tag or a participant) realizes. Useful to express acyclic graphs. +ruote has got a new "await" attribute (can be placed on any expression) that suspends the application of the expression until a condition (entering or leaving a tag or a participant) realizes. Useful when expressing graphs.   -[Ruote](http://ruote.rubyforge.org) is a Ruby workflow engine. It's mostly about orchestrating tasks, routing work among participants. The most interesting questions people come up with are the ones about "how to model that flow in ruote?". +[Ruote](http://ruote.rubyforge.org) is a Ruby workflow engine. It's about orchestrating tasks, routing work among participants. The most interesting questions people come up with are the ones about "how to model that flow in ruote?". The other day on IRC (freenode #ruote), Typedef asked me how one could model this in ruote: @@ -37,28 +37,14 @@ end {% endhighlight %} -The rectangle is the top sequence, when the concurrence is done, C gets applied. The concurrence makes sure A and B are applied in parallel, the inner sequence align D after B and the :forget flag is here to let the B branch reply to the concurrence right after B finishes. +The rectangle is the top sequence, when the concurrence is done, C gets applied. The concurrence makes sure A and B are applied concurrently, the inner sequence align D after B and the :forget flag is here to let the B branch reply to the concurrence right after B finishes. -But, conceptually, that is more like the graph on the right, where D becomes an orphan and the main flow goes on without waiting for it. It's not explicitely demanded but I think that this piece of flow ends when all its tasks completed (hence the rectangle I draw). +But, conceptually, that is more like the graph on the right, where D becomes an orphan and the main flow goes on without waiting for it. It's not explicitely required, but I think that this piece of flow should end when all its tasks completed (hence the rectangle I draw). So I went back to the coding board. I wrote the four tasks in a concurrence and told myself: "this is great, the four tasks exist in the same space, when all four of them terminate, the concurrence terminates..." -
-{% highlight ruby linenos %} -# -# everybody at the same time -# -concurrence do - a - b - c - d -end -{% endhighlight %} -
- I wondered how I could materialize Typedef's arrows. And I realized that he was probably right trying to apply [await](http://ruote.rubyforge.org/exp/await.html), this expression could shine in this scenario. This "await" expression is a rework of the [listen](http://ruote.rubyforge.org/exp/listen.html) expression. It's meant for waiting for events to happen in other branches of the workflow execution tree. @@ -89,9 +75,7 @@ end There are 3 kind of events "await" can listen to: participant (on apply and on reply), tag (on entering and on leaving) and errors. -The problem with this definition is that it nevers exits, the two await expressions behave like little daemons, wait for the that to be left. That's how "await" (and "listen") are supposed to work, when they have a block they become daemons. - -The solution would be to use "await" without a block. It then behaves like a lock, waiting for the event to happen to let the flow resume. +The problem with this definition is that it never exits, the two await expressions behave like little daemons, that's how "await" (and "listen") are supposed to work, when they have a block they become daemons.
{% highlight ruby linenos %} @@ -116,16 +100,16 @@ end {% endhighlight %}
-But, although it behaves as we wanted, it feels clunky compared to the "daemons" version above. +The solution would be to use "await" without a block. It then behaves like a lock, waiting for the event to happen to let the flow resume. -So I went ahead and added an :await attribute to the ruote expressions. When an expression sports it, it waits for the described event before applying for real (it stays in a paused state until the event occurs). +But, although it runs as we wanted, the definition feels clunky compared to the "daemons" version above. -The resulting process definition looks like: +So I went ahead and added an :await attribute to the ruote expressions. When an expression sports it, it waits for the described event before applying for real (it stays in a paused state until the event occurs).
{% highlight ruby linenos %} # -# xxx +# using the new :await attribute # concurrence do sequence :tag => 'ab' do @@ -142,3 +126,46 @@ end {% endhighlight %}
+ +This new "await" attribute can express things like + +* ```:await => "left_tag:x"``` +* ```:await => "reached_participant:alfred"``` + +The bare + +```:await => "b"``` + +is a shortcut for + +```:await => "left_tag:b"``` + +I think this "wait for a tagged region to terminate" scenario is important and deserves a short notation. + +
+{% highlight ruby linenos %} +# +# short version +# +concurrence do + sequence :tag => 'ab' do + a + b :tag => 'b' + end + c :await => 'ab' + d :await => 'b' +end +{% endhighlight %} +
+ +I've added some documentation about this new "await attribute" to the [common attributes](http://ruote.rubyforge.org/common_attributes.html) page and to the [await expression](http://ruote.rubyforge.org/exp/await.html) documentation. + +Here are the main links for ruote: + +* [http://ruote.rubyforge.org](http://ruote.rubyforge.org) (site) +* [https://github.com/jmettraux/ruote](https://github.com/jmettraux/ruote) (source) +* [http://groups.google.com/group/openwferu-users](http://groups.google.com/group/openwferu-users) (mailing list) +* freenode #ruote (irc) + +I wish you a Merry Christmas and a Happy New Year! + diff --git a/css/style.css b/css/style.css index eb7130e..a560e89 100644 --- a/css/style.css +++ b/css/style.css @@ -107,10 +107,12 @@ img { width: 47%; float: left; margin-right: 0.7em; + margin-bottom: 0.2em; } .half-code-right { width: 47%; float: right; margin-left: 0.7em; + margin-bottom: 0.2em; }