processi

about processes and engines

state machine

“where are we in the process ?” is a question often heard (in the realm of workflow / process engines). A way of thinking about workflow is the “state machine” way, thus dividing the concept among “states” and “transitions”. Most of the time, this works out well.

With a state machine, it is a rather easy question to answer. OpenWFE[ru] is not based on state machines, it’s rather an interpreter.

Someone will still ask the question.

participants, at the surface

With OpenWFE[ru], I always sticked to the “you’re where there is a workitem that surfaced” explanation, that means, the state of a process instance is determined by the set of its workitems currently held by the participants.

# some setup  (OpenWFEru 0.9.17)

require 'openwfe/def'
require 'openwfe/engine'
require 'openwfe/participants'

engine = OpenWFE::Engine.new

alice = engine.register_participant(
    :alice, OpenWFE::HashParticipant)
bob = engine.register_participant(
    :bob, OpenWFE::HashParticipant)

class MyDefinition < OpenWFE::ProcessDefinition
    sequence do
        alice
        bob
    end
end

# later ...

fei = engine.launch MyDefinition
    # fei will hold the id to the root expression
    # of the newly launched process instance

sleep 0.050
    # it's asynchronous, so...

puts "alice holds #{alice.size} workitem(s)"
puts "bob   holds #{bob.size} workitem(s)"

# (not doing anything meaningful with the workitem
#  in this example...)

will produce something like

alice holds 1 workitem(s)
bob   holds 0 workitem(s)

We have one process instance and its “state” is at “alice”.

But now, what if the workitem is asleep, somewhere in a sleep expression, or in a when expression ? Only workitems in a participant would be listed, thus a sleeping process instance would be “nowhere”.

expressions, just under the surface

Not all participants may be accessible and I’ve just mentioned this sleep issue. It also seems more natural to ask directly to the engine about the “state” of a process instance than trying to determine that from potentially scattered participants.

puts engine.process_status(fei)

will yield something like :

-- OpenWFE::ProcessStatus --
      wfid : 20071203-gidushipamo
      expressions :
         (fei 0.9.17 engine field:__definition My 0 
20071203-gidushipamo alice 0.0.0)
      tags : 
      errors : 0
      paused : false

Now, we know that our process instance “20071203-gidushipamo” is currently at the “alice” participant (see the ‘expressions’ in the output.

But what if the participant “alice” appears at different ‘stages’ in our [business] process ? The expression id (position in the process definition tree) is “0.0.0″, OK, but what if the process changes ? (It will). What if we wanted something more expressive, something like a “state label” ? It could even encompass more than one participant / expression.

using process variables

We could use a variable bound at the process instance level (“/state”) and update it whenever our process enters a new stage.

class My2ndDefinition < OpenWFE::ProcessDefinition
    sequence do
        at :state => "redaction"
        alice
        at :state => "correction"
        bob
        alice
        at :state => "approval"
        charly
    end

    process_definition :name => "at" do
        set :var => "/state", :val => "${state}"
    end
end

fei = engine.launch My2ndDefinition

sleep 0.050

puts "state : " + engine.lookup_variable(
    'state', fei.workflow_instance_id)

will produce :

state : redaction

I have used here a [sub-]process definition, it’s perfectly fine to think of it as a function.

Not a bad technique. I should perhaps include an ‘at’ or an ‘entering’ expression to OpenWFEru (entering :stage => "x")… I’ll think about it.

In business process management, there is an ongoing effort to turn sequential processes into sets of concurrent processes. It could mean we have a process instance that has multiple states. It doesn’t seem too difficult to cope with this, but…

abusing tags, just under the surface

The OpenWFEru process definition language has redo and undo expressions. They use a :tag facility, any expression may be tagged and later redone or undone. A tag, behind the scenes, is just a variable like any other. With a “/” (slash) prefix, you can bind a tag at the process level (like the “/state” variable in the previous section).

This tag system being already available, why not using it for denoting state ?

That leads us to :

class My3rdDefinition < OpenWFE::ProcessDefinition
    sequence do
        alice :tag => "redaction"
        sequence :tag => "correction" do
            bob
            alice
        end
        charly :tag => "approval"
    end
end

fei = engine.launch My3rdDefinition

sleep 0.050

puts "state : " + engine.process_status(
    fei.workflow_instance_id).tags.inspect

which outputs :

state : ["redaction"]

We thus have an array of tags (tag names). We can use tags with “undo” and “redo” to easily track some state in the business processes.

conclusion

I have shown three techniques for tracking state. The first one, focusing on participants only was what I initially thought for OpenWFE[ru].

The second and third techniques show a “state” concept that (1) doesn’t require querying the participants, (2) spans multiple participants or expressions.

I hope this long post also shed some light on the OpenWFEru [business] process engine. Questions are welcome on the OpenWFEru users mailing list.

Written by John Mettraux

December 3, 2007 at 9:58 am

Posted in bpms, openwferu, ruby, workflow

4 Responses

Subscribe to comments with RSS.

  1. blah?

    Nikc

    December 3, 2007 at 12:06 pm

  2. Hi Nikc,

    this is fixed. Though I still feel like rewriting the conclusion… Nice website btw, I like the mainframe picture :)

    Thanks a lot,

    John

    John Mettraux

    December 3, 2007 at 12:14 pm

  3. “But what if the participant “alice” appears at different ’stages’ in our [business] process ?” — Having a single human being performing multiple tasks within one large business model, is exactly what I use most. Using any of the techniques above solves the issue, but I think it would be great to have a single documented (preferred) way to label tasks.

    For example: maybe some future version of Densha’s fluo would want to show some task label within the rounded BPMN activity boxes. For that, it would need to know what specific tag or variable name is to be used.

    So, even though OpenWFE[ru] is based on participants, maybe denote the “:tag” as being the preferred way to label tasks?

    Arjan van Bentem

    April 12, 2008 at 1:28 pm

  4. Hello Arjan,

    :tag can denote any expression in the process definitions.

    But I will let Fluo use :tag as well as the current :activity for an “activity label”

    http://rubyforge.org/tracker/index.php?func=detail&aid=19457&group_id=2609&atid=10195

    Feel free to join the OpenWFEru users mailing list for further discussions

    http://groups.google.com/group/openwferu-users

    Thanks for your suggestion, best regards

    John Mettraux

    April 12, 2008 at 2:31 pm


Comments are closed.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: