<br>I needed to to define multiuser web workflows in the most transparent way. I wondered if a state monad could transparently bring automatic checkpointing of each action and automatic resume after failure. In this way a long living computation could be expressed in a single monadic computation.<br>
<br>Additionally,&nbsp; for inter process communications,&nbsp; this package&nbsp; includes a primitive for&nbsp; activating a workflow whenever any action result meet certain condition. There are also primitives for start/restart processes,&nbsp; retrieval of intermediate results and unsafe IO actions inside the state monad...<br>
<br><a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Workflow">http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Workflow</a><br><br><br>Cabal description:<br><br>Transparent low level support (state logging, resume of the computation, wait for data condition) for long living, event driven processes.<br>
<br>&nbsp;Workflow give the two first services to any monadic computation of type  (a-&gt; m a)
usually m=IO<br><br>f x &gt;&gt;=\x&#39;-&gt; g x&#39; &gt;&gt;= \x&#39;&#39;-&gt;... z <br><br>by
prefixing the user with the method &quot;step&quot;:
<br><br>step f  x &gt;&gt;= \x&#39;-&gt; step g  x&#39; &gt;&gt;= \x&#39;&#39;-&gt;...
<br><br>This means that a workflow can be described with the familiar &quot;do&quot; notation. In principle, there is no other limitation
on the syntax but the restriction (a -&gt; m a): All computations consume and produce the same type of data. do notation is supported fully.<br><br><br><br><br>Workflow export a few primitives that bring the following services:<br>
<br>- transparent checkpointing of each step in permanent storage using TCache&nbsp; (step)
<br>- resume of the monadic computation at the last checkpoint after soft or hard interruption
<br>- use of versioning techniques for storing object changes (using RefSerialize)
<br>- retrieval of the object at any previous step
<br>- suspend the computation (waitFor) until the input object meet certain conditions. useful for inter-workflow
comunications.
<br><br><br>At the end of the workflow all the intermediate data is erased.
see demos and the header of Control.TCache for documentation.
<br><br><br>This is a piece of code is a loop that imput numbers (demo.hs). there
is another process, that check the numbers entered and return Finish when
match the desired number. that is detected by this thread and finalize.
When number of tries are 9, The process finish, this is detected by the other
process and finalizes also. <br>
That ilustrates the use of event handling (waitFor) and step execution.<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
askNumbers name d = do <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; step2 $&nbsp; threadDelay 5000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- wait for the other tread to process.<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r &lt;- step (waitFor anything)
d&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- get the last value of the object
with key &quot;try-finish&quot;, to look for the other thread actions<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case r of<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Finish msg -&gt;&nbsp; step2 $ print&nbsp;
msg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
--the other thread sent a finalize response<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Try 9 num&nbsp; -&gt;&nbsp; step1 $ return $ Finish&nbsp; &quot;sorry, no more
guesses&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --send finalization to the wait thread<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _ -&gt; do <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nd &lt;- step&nbsp; (askNumber name) d<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; askNumbers name nd <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; anything= \_-&gt; True&nbsp; <br>