6

(and alternatives to a workflow engine)

Problem: I have various inputs with various attributes. For example {name: john, country: US} and {name: Jose, country: MX}

And I have the following workflows for the task Enter Country

US citizen:

Step1 Validate US Passport

Step2 Declare Goods at Customs

Non US citizen

Step1 Provide Visa

Step2 Validate Country passport

Step3 Declare Goods at Customs

(Bear with me as I am trying to think of a coherent example)

There are steps that are shared between workflows and depending on result (pass or fail) it can trigger another task (something like Rejected from country)

The two options are:

  • Place the decision logic on each step itself, where the inputs are provided.

    • pros - no duplication.
    • cons - complicated to read what steps are used.
  • Place the decision as the first step and have it pick a workflow as the initial step

    • pros - easy to read.
    • cons - possible duplication.

In the future there maybe a need to float this logic to the users to create custom workflows.

What is the best approach for this type of problem?

2 Answers 2

2

Separate your concerns: you have actions and you have workflow that can call actions.

The actions can be defined as functions. The workflow can be defined as a list of functions that are applied to a dictionary. You can then put the workflows in a dictionary so you can find them easily.

def validate_passport(env_dict):
    ...

def provide_visa(env_dict):
    ...

def declare_goods(env_dict):
    ...

us_citizen_workflow = [ validate_passport, declare_goods ]
mex_citizen_workflow = [ provide_visa, validate_passport, declare_goods ]

workflows_by_country = { "US":us_citizen_workflow,  
                         "MEX":mex_citizen_workflow }

def process_entry(person):
    env_dict = person.copy()
    for work_step in workflows_by_country[person["country"]]:
        work_step(env_dict)
    return env_dict["entry_status"]

Elaborations would include workflows that call other workflows, short circuit exits (likely by throwing exceptions), debugging facilities that allow checking for the validity of the environment dictionary between steps, etc.

1
  • Thanks for the answer. This seems to be a combination of the two. Problem is that I am trivializing the example. There is going to be a lot more than 3 steps and a lot more conditions than just the country of origin in my real use case. I was hoping to get more answers regarding pros/cons of both approaches since I think the implementation details are clear to me. Based on my research and lack of answers here I think like a lot of things "it depends" seems to be the answer. Mar 28, 2016 at 16:28
1

I came across this question looking for a similar answer myself. What I have found is the "Rete Algorithm", which is well explained here: https://techondec.wordpress.com/2011/03/14/rete-algorithm-demystified-part-2/

For your example, country would then be an Alpha node, below which each country(-group) hangs, and onto which you connect the actions, which are your worklow steps. After picking the steps you would have to sort them by a certain order.

I have no example of how this would look code-wise though. I find references to "Pychinko" as a Rete implementation, but most links I could find were dead. It seems like somebody included it here in their repo, but there is no documentation: https://github.com/mit-dig/air-reasoner/tree/master/pychinko. In the same repo there is another rete.py in that repo which states "a rete implementation independant of pychinko, that uses IndexedFormula".

Otherwise there are rules engines like PEAK-rules for example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.