Add asynchronous actions doc
Change-Id: Idef3fed51099875d2200b1a29af152be23a0215f Implements: blueprint mistral-async-actions-doc
This commit is contained in:
parent
207d59d408
commit
cf0cc484bc
141
doc/source/developer/asynchronous_actions.rst
Normal file
141
doc/source/developer/asynchronous_actions.rst
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
=====================================
|
||||||
|
How to work with asynchronous actions
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
*******
|
||||||
|
Concept
|
||||||
|
*******
|
||||||
|
|
||||||
|
.. image:: /img/Mistral_actions.png
|
||||||
|
|
||||||
|
During a workflow execution Mistral eventually runs actions. Action is a particular
|
||||||
|
function (or a piece of work) that a workflow task is associated to.
|
||||||
|
|
||||||
|
Actions can be synchronous and asynchronous.
|
||||||
|
|
||||||
|
Synchronous actions are actions that get completed without a 3rd party, i.e. by
|
||||||
|
Mistral itself. When Mistral engine schedules to run a synchronous action it sends
|
||||||
|
its definition and parameters to Mistral executor, then executor runs it and upon
|
||||||
|
its completion sends a result of the action back to Mistral engine.
|
||||||
|
|
||||||
|
In case of asynchronous actions executor doesn't send a result back to Mistral.
|
||||||
|
In fact, the concept of asynchronous action assumes that a result won't be known
|
||||||
|
at a time when executor is running it. It rather assumes that action will just
|
||||||
|
delegate actual work to a 3rd party which can be either a human or a computer
|
||||||
|
system (e.g. a web service). So an asynchronous action's run() method is supposed
|
||||||
|
to just send a signal to something that is capable of doing required job.
|
||||||
|
|
||||||
|
Once the 3rd party has done the job it takes responsibility to send result of
|
||||||
|
the action back to Mistral via Mistral API. Effectively, the 3rd party just needs
|
||||||
|
to update the state of corresponding action execution object. To make it possible
|
||||||
|
it must know corresponding action execution id.
|
||||||
|
|
||||||
|
It's worth noting that from Mistral engine perspective the schema is essentially
|
||||||
|
the same in case of synchronous and asynchronous actions. If action is synchronous,
|
||||||
|
then executor immediately sends a result back with RPC mechanism (most often,
|
||||||
|
a message queue as a transport) to Mistral engine after action completion. But
|
||||||
|
engine itself is not waiting anything proactively, its architecture is fully on
|
||||||
|
asynchronous messages. So in case of asynchronous action the only change is that
|
||||||
|
executor is not responsible for sending action result, something else takes over.
|
||||||
|
|
||||||
|
Let's see what we need to keep in mind when working with asynchronous actions.
|
||||||
|
|
||||||
|
******
|
||||||
|
How to
|
||||||
|
******
|
||||||
|
|
||||||
|
Currently, Mistral comes with one asynchronous action out of the box, "mistral_http".
|
||||||
|
There's also "async_noop" action that is also asynchronous but it's mostly useful
|
||||||
|
for testing purposes because it does nothing. "mistral_http" is an asynchronous
|
||||||
|
version of action "http" sending HTTP requests. Asynchrony is controlled by
|
||||||
|
action's method is_sync() which should return *True* for synchronous actions and
|
||||||
|
*False* for asynchronous.
|
||||||
|
|
||||||
|
Let's see how "mistral_http" action works and how to use it step by step.
|
||||||
|
|
||||||
|
We can imagine that we have a simple web service playing a role of 3rd party system
|
||||||
|
mentioned before accessible at http://my.webservice.com. And if we send an HTTP
|
||||||
|
request to that url then our web service will do something useful. To keep it
|
||||||
|
simple, let's say our web service just calculates a sum of two numbers provided
|
||||||
|
as request parameters "a" and "b".
|
||||||
|
|
||||||
|
1. Workflow example
|
||||||
|
===================
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
---
|
||||||
|
version: '2.0'
|
||||||
|
|
||||||
|
my_workflow:
|
||||||
|
tasks:
|
||||||
|
one_plus_two:
|
||||||
|
action: mistral_http url=http://my.webservice.com
|
||||||
|
input:
|
||||||
|
params:
|
||||||
|
a: 1
|
||||||
|
b: 2
|
||||||
|
|
||||||
|
So our workflow has just one task "one_plus_two" that sends a request to our web
|
||||||
|
service and passes parameters "a" and "b" in a query string. Note that we specify
|
||||||
|
"url" right after action name but "params" in a special section "input". This is
|
||||||
|
because there's no one-line syntax for dictionaries currently in Mistral. But both
|
||||||
|
"url" and "params" are basically just parameters of action "mistral_http".
|
||||||
|
|
||||||
|
It is important to know that when "mistral_http" action sends a request it includes
|
||||||
|
special HTTP headers that help identify action execution object. These headers are:
|
||||||
|
|
||||||
|
- **Mistral-Workflow-Name**
|
||||||
|
- **Mistral-Workflow-Execution-Id**
|
||||||
|
- **Mistral-Task-Id**
|
||||||
|
- **Mistral-Action-Execution-Id**
|
||||||
|
- **Mistral-Callback-URL**
|
||||||
|
|
||||||
|
The most important one is "Mistral-Action-Execution-Id" which contains an id of
|
||||||
|
action execution that we need to calculate result for. Using that id a 3rd party
|
||||||
|
can deliver a result back to Mistral once it's calculated. If a 3rd party is a
|
||||||
|
computer system it can just call Mistral API via HTTP using header
|
||||||
|
"Mistral-Callback-URL" which contains a base URL. However, a human can also do
|
||||||
|
it, the simplest way is just to use Mistral CLI.
|
||||||
|
|
||||||
|
Of course, this is a practically meaningless example. It doesn't make sense to use
|
||||||
|
asynchronous actions for simple arithmetic operations. Real examples when asynchronous
|
||||||
|
actions are needed may include:
|
||||||
|
|
||||||
|
- **Analysis of big data volumes**. E.g. we need to run an external reporting tool.
|
||||||
|
- **Human interaction**. E.g. an administrator needs to approve allocation of resources.
|
||||||
|
|
||||||
|
In general, this can be anything that takes significant time, such as hours, days
|
||||||
|
or weeks. Sometimes duration of a job may be even unpredictable (it's reasonable
|
||||||
|
though to try to limit such jobs with timeout policy in practice).
|
||||||
|
The key point here is that Mistral shouldn't try to wait for completion of such
|
||||||
|
job holding some resources needed for that in memory.
|
||||||
|
|
||||||
|
An important aspect of using asynchronous actions is that even when we interact
|
||||||
|
with 3rd party computer systems a human can still trigger action completion by
|
||||||
|
just calling Mistral API.
|
||||||
|
|
||||||
|
|
||||||
|
2. Pushing action result to Mistral
|
||||||
|
===================================
|
||||||
|
|
||||||
|
Using CLI:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ mistral action-execution-update <id> --state SUCCESS --output 3
|
||||||
|
|
||||||
|
This command will update "state" and "output" of action execution object with
|
||||||
|
corresponding id. That way Mistral will know what the result of this action
|
||||||
|
is and decide how to proceed with workflow execution.
|
||||||
|
|
||||||
|
Using raw HTTP:
|
||||||
|
|
||||||
|
.. code-block:: HTTP
|
||||||
|
|
||||||
|
POST <Mistral-Callback-URL>/v2/action-executions/<id>
|
||||||
|
|
||||||
|
{
|
||||||
|
"state": "SUCCESS",
|
||||||
|
"output": 3
|
||||||
|
}
|
@ -5,5 +5,6 @@ Developer's Reference
|
|||||||
:maxdepth: 3
|
:maxdepth: 3
|
||||||
|
|
||||||
creating_custom_action
|
creating_custom_action
|
||||||
|
asynchronous_actions
|
||||||
devstack
|
devstack
|
||||||
troubleshooting
|
troubleshooting
|
||||||
|
@ -15,6 +15,8 @@ and result. Third party service should do a request to Mistral API and provide i
|
|||||||
|
|
||||||
.. image:: /img/Mistral_actions.png
|
.. image:: /img/Mistral_actions.png
|
||||||
|
|
||||||
|
:doc:`How to work with asynchronous actions </developer/asynchronous_actions>`
|
||||||
|
|
||||||
System Actions
|
System Actions
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
@ -23,6 +25,7 @@ actions for specific Mistral installation via a special plugin mechanism.
|
|||||||
|
|
||||||
:doc:`How to write an Action Plugin </developer/creating_custom_action>`
|
:doc:`How to write an Action Plugin </developer/creating_custom_action>`
|
||||||
|
|
||||||
|
|
||||||
Ad-hoc Actions
|
Ad-hoc Actions
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user