public
Description: A rich DSL for describing state, and state-related behaviour, in your ruby classes / models.
Homepage: nil
Clone URL: git://github.com/davidlee/state-fu.git
state-fu / WORKFLOW.textile
100644 190 lines (142 sloc) 5.62 kb

http://openwferu.rubyforge.org/patterns.html

Could StateFu model the workflow patterns presented here (as Ruote
does)?

The short answer is: it could probably be used to model them in some
way, as parts of a larger whole, but cannot (currently) express all of
them within a single Machine or other unified context – and cannot do
so without incorporating external libraries to deal with process
management, etc.

A StateFu Machine is concerned with one state, associated with one
object. Transitions between these states can occur; both guard
conditions and behaviours can be attached to state entry and exit, and
to event execution; multiple machines may exist, tracking different
states, for a given object.

But at its core, it is a state machine; it knows nothing of
processes. Ruote is fundamentally different: the basic units with
which it constructs workflows are not states and events, but processes
and participants.

That said, it’s unclear whether this is an impediment to using StateFu
to model “workflows” as we understand the term in [ some application ]. If the
problem does not demand a full-blown (capitals) Workflow Engine, I
suspect it’s best avoided for simplicity’s sake:

http://www.opensourcery.co.za/2009/07/06/driving-business-processes-in-ruby/

“Workflow engines are business process operating systems.”

“Glad you like it, but be careful. As wonderful as the BPM/WFE world
sounds, it is a serious leap to take. First off all make sure that
your situation necessitates a workflow engine. I’ve pointed a lot of
people to a simpler daemon-kit + AMQP combination for their needs when
asking about ruote. In the majority of simple automated tasks a state
machine with worker processes will suffice. ruote is all about
business processes and automating those processes.”


Sequence

http://workflowpatterns.com/patterns/control/basic/wcp1.php

“… a series of consecutive tasks which execute in turn one after the
other. Two tasks form part of a Sequence if there is a control-flow
edge from one of them to the next which has no guards or conditions
associated with it.”

On first inspection, the following would appear to be roughly
equivalent:

Ruote (ruby)


sequence do
  alpha
  bravo
End

StateFu


event :change, :from => { :alpha => :bravo }

But, in Ruote, alpha and bravo are not states; they are participants …



h2. Parallel Split / Concurrence / Fork

http://workflowpatterns.com/patterns/control/basic/wcp2.php

“The divergence of a branch into two or more parallel branches each of
which execute concurrently.”

Ruote


concurrence do
 alpha
 bravo
end

StateFu (state branching)


event :fork, :from => :alpha, :to => [:bravo, :charlie]

The StateFu example above creates an event with two possible
destinations – but exactly one must be chosen. To represent
concurrency, at least one other machine would need to be invoked, one
machine firing a transition in the other. This itself is fairly
trivial in StateFu, but shows the limits of its orientation towards
state: the workflow is no longer described in a single, unified block.

To actually implement concurrent process management (as Ruote does),
you’d need some code, or a framework, to deal with managing and
scheduling those processes. It’s pretty easy to use StateFu to drive
asynchronous processes, but not to manage parallelism and certain
other types of flow control like branching / merging of those
processes.

So … StateFu could be used with other libraries to implement this
kind of functionality. To actually desribe and drive it in a
concise, unified way, it would need some additional features. As to
whether either approach would be appropriate to [ some project ], I can’t
say without more solid requirements and some time to think / discuss.


Synchronization ( AND-join, rendezvous, synchronizer )

I think the discussion above pretty much covers it.


Exclusive Choice ( OR )

Ruote


_if do
  equals :field_value => :x, :other-value => "y"
   participant :theodor # then
   participant :emma    # else
end

StateFu


state( :pending_delivery) do
 event :deliver_to_folder, :to => :project_folder do
    requires :auto_sort_rule?
 end
  event :deliver_to_inbox, :to => :inbox do
    requires :no_auto_sort_rule?   # evaluates to !auto_sort_rule?
  end
end

The examples are obviously not equivalent, but I believe the answer is
yes. Syntactic sugar is easy to add if this is a frequently recurring
pattern.


Simple merge (XOR-join, exclusive OR-join, asynchronous join, merge)

“After the case-payment or provide-credit tasks, initiate the
product-receipt task.”

Ruote:

“The ‘simple merge’ is implicitly supported by the ‘if’ and ‘case’
expressions.”

StateFu:

As per #2 & #3: yes for states, no for concurrent processes.

In summary, Ruote and BPMs in general operate at a higher level of
abstraction, and look at problems in different terms to state-machine
based engines; they are suited to different tasks, and either or both
may be suited to any particular application.

Ruote appears to require substantially more work to set up (as it has
its own scheduler, process management, etc).

As development of StateFu proceeds, I’ll investigate the limitations
of the state-based model and explore integration with some third party
libraries also (eventmachine and AMQP spring to mind) … it should be
interesting to see where this leads.