Which Workflow Engine do you recommend?

workflow

I am kicking around the idea of using a workflow engine on this upcoming project. We know that there is a lot of caveats with using a workflow engine and we have a lot of development experience in many platforms so we would be willing to let the choice of workflow engine take precedence over our favorite toolset or developer IDE.

We are more interested in internal workflow (i.e. petri net for easily changeable ERP purposes without involving additional coder time) than external workflow (i.e. aggregating SOAP calls into a transaction aware, higher level SOA). Which workflow engine would you recommend? We have superficially looked at offerings by Oracle, Microsoft, and some open source stuff too. It's all very overwhelming so please respond only if you have real life experience with implementing internal workflow.

Best Solution

If you can use a state machine, then I'd recommend an open source project called StateLess by Nicholas Blumhardt (Autofaq creator). His approach avoids the issue of long running workflows being held by a runtime engine, as the state is defined by a simple variable such as a string or int.

Here is a sample state machine:

var phoneCall = new StateMachine<State, Trigger>(State.OffHook);

phoneCall.Configure(State.OffHook)
    .Permit(Trigger.CallDialed, State.Ringing);

phoneCall.Configure(State.Ringing)
    .Permit(Trigger.HungUp, State.OffHook)
    .Permit(Trigger.CallConnected, State.Connected);

phoneCall.Configure(State.Connected)
    .OnEntry(() => StartCallTimer())
    .OnExit(() => StopCallTimer())
    .Permit(Trigger.LeftMessage, State.OffHook)
    .Permit(Trigger.HungUp, State.OffHook)
    .Permit(Trigger.PlacedOnHold, State.OnHold);

// ...

phoneCall.Fire(Trigger.CallDialled);
Assert.AreEqual(State.Ringing, phoneCall.State);

Your state can be an integer which will allow you to feed it the current state from a database. This can be set on the constructor of the state machine as follows:

var stateMachine = new StateMachine<State, Trigger>(
    () => myState.Value,
    s => myState.Value = s);

You can implement this in just one assembly, compared to the multiple projects you need to run Windows Workflow. Maintenance is extremely low, there is no "designer" that generates code for your, etc. Again, it is simple, and there lies the beauty.

Related Question