Parallelism in SonataFlow
This document describes how you can run parallel tasks in SonataFlow.
The testing procedure described in this document is based on the serverless-workflow-service-calls-quarkus
example application in GitHub repository.
SonataFlow serializes the execution of parallel tasks. Therefore, the word "parallel" does not indicate simultaneous execution, but it means that there is no logical dependency between the execution of branches. An inactive branch can start or resume the execution of a task without waiting for an active branch to be completed, in case the latter suspends the execution (for example, wait for an event reception). |
The serverless-workflow-service-calls-quarkus
example application is a workflow that concatenates three strings and returns a result. The concatenation in the example application is done in parallel, which includes one branch per three strings.
Creating a parallel workflow
You can create a workflow, which performs a series of parallel tasks.
-
A workflow project is created.
For more information about creating a workflow project, see Creating your first Serverless Workflow service.
-
Create a workflow file named as
parallel.sw.json
under thesrc/main/resources/
directory. -
Add the following content to the
parallel.sw.json
file:Example content forparallel.sw.json
file{ "id": "parallel", "version": "1.0", "specVersion": "0.8", "name": "Welcome to the Parallel dimension", "description": "Testing parallelism", "start": "Parallel", "functions": [ { "name": "concatA", "type": "expression", "operation": ".result|=.+\"A\"" (1) }, { "name": "concatB", "type": "expression", "operation": ".result|=.+\"B\"" (2) }, { "name": "concatC", "type": "expression", "operation": ".result|=.+\"C\"" (3) } ], "states": [ { "name": "Parallel", "type": "parallel", (4) "branches": [ (5) { "name": "branchA", "actions": [ { "functionRef": "concatA" (6) } ] }, { "name": "branchB", "actions": [ { "functionRef": "concatB" (7) } ] }, { "name": "branchC", "actions": [ { "functionRef": "concatC" (8) } ] } ], "completionType": "allOf", (9) "end": { "terminate": true } } ] }
1 Function that concatenates the string A
.2 Function that concatenates the string B
.3 Function that concatenates the string C
.4 Defines the type of the state as parallel
.5 Defines the branches that run in parallel. 6 Defines the function that runs in branchA
.7 Defines the function that runs in branchB
.8 Defines the function that runs in branchC
.9 Defines the completion type of the parallel state as allOf
. This means that the parallel state is completed when all the branches are completed.
Running a parallel workflow
After you create a workflow that performs a series of parallel tasks, you can run the workflow.
-
A parallel workflow is created.
For more information, see Creating a parallel workflow.
-
The workflow application is up and running.
You can start the workflow application in development mode by using the following command:
mvn quarkus:dev
-
To run the created parallel workflow, send a request to the
/parallel
endpoint as shown in the following example request:Example requestcurl -X 'POST' \ 'http://localhost:8080/parallel' \ -H 'accept: */*' \ -H 'Content-Type: application/json' \ -d '{}'
Example response{"id":"358f97ba-f0f9-4f25-86cc-4b35e85c2406","workflowdata":{"result":"ABC"}}
The
"result":"ABC"
in the previous example response might be different in each request since the branches are running in parallel and the execution order of the branches is unpredictable.Note that the parallel workflow data shows the concatenated string as result.
Running some branches in parallel workflow
You can define the "completionType": "atLeast"
to run only some branches in parallel workflow, instead of defining "completionType": "allOf"
. When you define "completionType": "atLeast"
, you also need to define the minimum number of branches that you want to run by defining the "numCompleted":
property.
-
A parallel workflow is created.
For more information, see Creating a parallel workflow.
-
Change the
completionType
property to"atLeast"
and add the"numCompleted": 2
property to the parallel state.Example parallel workflow{ "id": "parallel", "version": "1.0", "specVersion": "0.8", "name": "Welcome to the Parallel dimension", "description": "Testing parallelism", "start": "Parallel", "functions": [ { "name": "concatA", "type": "expression", "operation": ".result|=.+\"A\"" }, { "name": "concatB", "type": "expression", "operation": ".result|=.+\"B\"" }, { "name": "concatC", "type": "expression", "operation": ".result|=.+\"C\"" } ], "states": [ { "name": "Parallel", "type": "parallel", "branches": [ { "name": "branchA", "actions": [ { "functionRef": "concatA" } ] }, { "name": "branchB", "actions": [ { "functionRef": "concatB" } ] }, { "name": "branchC", "actions": [ { "functionRef": "concatC" } ] } ], "completionType": "atLeast", (1) "numCompleted": "2", (2) "end": { "terminate": true } } ] }
1 Defines the completion type of the parallel state as atLeast
.2 Defines the minimum number of branches that you want to run. This means that the parallel state is completed when at least two branches are completed. -
To run the created parallel workflow, send a request to the
/parallel
endpoint as shown in the following example:Example requestcurl -X 'POST' \ 'http://localhost:8080/parallel' \ -H 'accept: */*' \ -H 'Content-Type: application/json' \ -d '{}'
Example response{"id":"3da62df1-c4e7-48c9-a3e4-7f63872c92f4","workflowdata":{"result":"BC"}}
The
"result":"BC"
in the response might be different in each request.The parallel workflow data shows the concatenated string as result, but in this case, the workflow concatenates only two letters.
Found an issue?
If you find an issue or any misleading information, please feel free to report it here. We really appreciate it!