<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Following up on <span style="white-space: pre-wrap; "><a href="http://tinyurl.com/l8gtmsw">http://tinyurl.com/l8gtmsw</a></span> and <span style="white-space: pre-wrap; "><a href="http://tinyurl.com/n3v9lt8:">http://tinyurl.com/n3v9lt8:</a> </span> this explains how Mistral handles long running delegate tasks. Note that a 'passive' workflow engine can handle both normal tasks and delegates the same way. I'll also put that on ActionDesign wiki, after discussion.<div><font face="Calibri"><span style="font-size: 13px;"><br></span></font></div><div><font face="Calibri"><span style="font-size: 13px;"><b>Diagram: </b></span></font></div><div><div style="margin: 0px; "><a href="https://docs.google.com/a/stackstorm.com/drawings/d/147_EpdatpN_sOLQ0LS07SWhaC3N85c95TkKMAeQ_a4c/edit?usp=sharing" style="font-size: 13px;"><font face="Calibri">https://docs.google.com/a/stackstorm.com/drawings/d/147_EpdatpN_sOLQ0LS07SWhaC3N85c95TkKMAeQ_a4c/edit?usp=sharing</font></a></div><div style="margin: 0px; min-height: 22px; "><font face="Calibri"><span style="font-size: 13px;"><br></span></font></div><div style="margin: 0px; "><font face="Calibri"><span style="font-size: 13px;">1. On start(workflow), engine creates a new workflow execution, computes the first batch of tasks, sends them to ActionRunner [1].</span></font></div><div style="margin: 0px; "><font face="Calibri"><span style="font-size: 13px;">2. ActionRunner creates an action and calls action.run(input)</span></font></div><div style="margin: 0px; "><font face="Calibri"><span style="font-size: 13px;">3. Action does the work (compute (10!)), produce the results, and return the results to executor. If it returns, status=SUCCESS. If it fails it throws exception, status=ERROR.</span></font></div><div style="margin: 0px; "><font face="Calibri"><span style="font-size: 13px;">4. ActionRunner notifies Engine that the task is complete task_done(execution, task, status, results)[2]</span></font></div><div style="margin: 0px; "><font face="Calibri"><span style="font-size: 13px;">5. Engine computes the next task(s) ready to trigger, according to control flow and data flow, and sends them to ActionRunner.</span></font></div><div style="margin: 0px; "><font face="Calibri"><span style="font-size: 13px;">6. Like step 2: ActionRunner calls the action's run(input)</span></font></div><div style="margin: 0px; "><font face="Calibri"><span style="font-size: 13px;">7. A delegate action doesn't produce results: it calls out the 3rd party system, which is expected to make a callback to a workflow service with the results. It returns to ActionRunner without results, "immediately". </span></font></div><div style="margin: 0px; "><font face="Calibri"><span style="font-size: 13px;">8. ActionRunner marks status=RUNNING [?]</span></font></div><div style="margin: 0px; "><font face="Calibri"><span style="font-size: 13px;">9. 3rd party system takes 'long time' == longer then any system component can be assumed to stay alive. </span></font></div><div style="margin: 0px; "><font face="Calibri"><span style="font-size: 13px;">10. 3rd party component calls Mistral WebHook which resolves to engine.task_complete(workbook, id, status, results) </span></font></div><div style="margin: 0px; min-height: 22px; "><font face="Calibri"><span style="font-size: 13px;"><br></span></font></div><div style="margin: 0px; "><b style="font-size: 13px;"><font face="Calibri">Comments: </font></b></div><div style="margin: 0px; "><font face="Calibri"><span style="font-size: 13px;">* One Engine handles multiple executions of multiple workflows. It exposes two main operations: start(workflow) and task_complete(execution, task, status, results), and responsible for defining the next batch of tasks based on control flow and data flow. Engine is passive - it runs in a hosts' thread. Engine and ActionRunner communicate via task queues asynchronously, for details, see <a href="https://wiki.openstack.org/wiki/Mistral/POC">https://wiki.openstack.org/wiki/Mistral/POC</a> </span></font></div><div style="margin: 0px; "><font face="Calibri"><span style="font-size: 13px;"><br></span></font></div><div style="margin: 0px; "><font face="Calibri"><span style="font-size: 13px;">* Engine doesn't distinct sync and async actions, it doesn't deal with Actions at all. It only reacts to task completions, handling the results, updating the state, and queuing next set of tasks.</span></font></div><div style="margin: 0px; min-height: 22px; "><font face="Calibri"><span style="font-size: 13px;"><br></span></font></div><div style="margin: 0px; "><font face="Calibri"><span style="font-size: 13px;">* Only Action can know and define if it is a delegate or not. Some protocol required to let ActionRunner know that the action is not returning the results immediately. A convention of returning None may be sufficient. </span></font></div><div style="margin: 0px; min-height: 22px; "><font face="Calibri"><span style="font-size: 13px;"><br></span></font></div><div style="margin: 0px; "><font face="Calibri"><span style="font-size: 13px;">* Mistral exposes engine.task_done in the REST API so 3rd party systems can call a web hook.</span></font></div></div><div style="margin: 0px; "><font face="Calibri"><span style="font-size: 13px;"><br></span></font></div><div style="margin: 0px; "><font face="Calibri"><span style="font-size: 13px;">DZ.</span></font></div><div style="margin: 0px; "><font face="Calibri"><span style="font-size: 13px;"><br></span></font></div><div style="margin: 0px; "><div style="margin: 0px; "><font face="Calibri"><span style="font-size: 13px;">[1] I use ActionRunner instead of Executor (current name) to avoid confusion: it is Engine which is responsible for executions, and ActionRunner only runs actions. We should rename it in the code.</span></font></div><div style="margin: 0px; "><font face="Calibri"><span style="font-size: 13px;"><br></span></font></div><div style="margin: 0px; "><font face="Calibri"><span style="font-size: 13px;">[2] I use task_done for briefly and out of pure spite, in the code it is conveny_task_results.</span></font></div></div></body></html>