Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 20 additions & 18 deletions docs/operators/switch-task.mdx → docs/operators/switch-task.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,36 @@ import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Switch Task
Used to create branching logic.

A switch task is a representation of multiple `if...then...else` or `switch...case` statements in programming.

```json
"type" : "SWITCH"
```

## Configuration
* A switch task takes and expression as input along with multiple branches that contains a sequence of tasks to be executed and a *default* branch that is executed if no matching branches are found.
The switch task is used for creating branching logic. It is a representation of multiple `if...then...else` or `switch...case` statements in programming.

## Configurations
* A switch task takes an expression as input along with multiple branches containing a sequence of tasks to be executed and a *default* branch to be executed if no matching branches are found.
* The output of the **expression** is matched with the name of the branch.
* The expression can be a **javascript** expression of a value parameter which represents the input to the task directly.

Following are the task configuration parameters :
### Input Parameters

|name|type|description|
|Attribute|Description|
|---|---|
|evaluatorType|Type of the evaluator used. Supported types: **value-param**, **javascript**, **graaljs**.|
|expression|The expression that depends on the evaluator type. For the **value-param** evaluator, the expression is the input parameter; for the **javascript** and **graaljs** evaluator, it is the javascript expression.|
|decisionCases|Map where the key is possible values that can result from the **expression** with the value being the list of tasks to be executed.|
|defaultCase|List of tasks to be executed when no matching value is found in decision case (default condition)|
|evaluatorType|Indicates the type of evaluator used. Supported types are **value-param**, **javascript**, and **graaljs**.|
|expression|The expression depends on the evaluator type. For the **value-param** evaluator, the expression is the input parameter; for the **javascript** and **graaljs** evaluator, it is the javascript expression.|
|decisionCases|Map where the key is possible values that can result from the **expression**, with the value being the list of tasks to be executed.|
|defaultCase|List of tasks to be executed when no matching value is found in decision case (default condition).|

#### Types of evaluators
|name|description|
#### Types of Evaluators
|Attribute|Description|
|---|---|
| value-param | Use a parameter directly as the value |
| value-param | Use a parameter directly as the value. |
| javascript | Evaluate Javascript expressions and compute the value - Legacy. Deprecated.|
| graaljs | Evaluate Javascript expressions and compute the value, allows you to use ES6 compatible Javascript |
| graaljs | Evaluate Javascript expressions and compute the value. Allows you to use ES6 compatible Javascript. |


## Example
## Examples

Workflow with the switch task definition that uses **value-param** evaluatorType:

Expand Down Expand Up @@ -77,14 +76,17 @@ This is a banana 🍌
<TabItem value="javascript" label="Javascript">
This is a banana 🍌
</TabItem>
<TabItem value="clojure" label="Clojure">
This is a banana 🍌
</TabItem>
</Tabs>

<details><summary>Using Javascript expressions</summary>
<p>

When using **javascript** or **graaljs** as the evaluator type, the expression can be a javascript expression that returns a string.

The input to the tasks are available as the variables inside `$` scope within the script.
The input to the tasks is available as the variables inside the `$` scope within the script.

```json
{
Expand Down Expand Up @@ -122,5 +124,5 @@ Switch task can be nested just like nested if...then...else.
</details>

:::tip Switch task with other operators
Similar to any programming language, you can have other operators inside a switch case such as nested switch, loops, forks, etc.
Similar to any programming language, you can have other operators inside a switch case, such as nested switch, loops, forks, etc.
:::
266 changes: 266 additions & 0 deletions docs/operators/while.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
# While Loop

```json
"type" : "DO_WHILE"
```
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

The Do While task sequentially executes a list of tasks as long as a condition is true. The list of tasks is executed first, before the condition is checked, even for the first iteration.

## Configurations

* When scheduled, each task of this loop will see its `taskReferenceName` concatenated with **__i**, with **i** being the iteration number, starting at 1. **Warning**: `taskReferenceName` containing arithmetic operators must not be used.
* Each time the task is performed, the output is saved and indexed by the iteration value. This makes it possible for the condition to check the output of a specific task iteration. (E.g., `$.LoopTask['iteration]['first_task']`).
* The DO_WHILE task is set to *FAILED* as soon as one of the loopTask fails. In such cases, for the retry, the iteration starts from 1.

### Input Parameters

| Attributes | Description |
| -- | -- |
| loopCondition | Indicates the condition to be evaluated after every iteration. Supported types are **value-param**, **javascript**, and **graaljs**. If an exception occurs during evaluation, the task is set to FAILED_WITH_TERMINAL_ERROR. |
| loopOver | Includes the list of tasks to be executed as long as the condition is true. |

### Output Parameters​

| Attributes | Description |
| -- | -- |
| iteration | Indicates the iteration number, which is the current one while executing, and the final one once the loop is finished. |
| i | Iteration number as a string mapped to the task references names and their output. |
| * | Any state can be stored here if the loopCondition does so. For example, `storage` will exist if loopCondition is `if ($.LoopTask['iteration'] <= 10) {$.LoopTask.storage = 3; true } else {false}`. |

> **_NOTE:_**
* Domain or isolation group execution is unsupported.
* Nested DO_WHILE is unsupported. However, we can achieve a similar functionality as the DO_WHILE task supports SUB_WORKFLOW as a loopOver task.
* Since loopOver tasks will be executed in a loop inside the scope of a parent, the do-while task may not work as expected if it includes branching that crosses outside the DO_WHILE task.
* Branching inside the loopOver task is supported.

## Examples

<Tabs>
<TabItem value="JSON" label="JSON">

```json
{
"name": "Loop Task",
"taskReferenceName": "LoopTask",
"type": "DO_WHILE",
"inputParameters": {
"value": "${workflow.input.value}"
},
"loopCondition": "if ( ($.LoopTask['iteration'] < $.value ) || ( $.first_task['response']['body'] > 10)) { false; } else { true; }",
"loopOver": [
{
"name": "first task",
"taskReferenceName": "first_task",
"inputParameters": {
"http_request": {
"uri": "http://localhost:8082",
"method": "POST"
}
},
"type": "HTTP"
},{
"name": "second task",
"taskReferenceName": "second_task",
"inputParameters": {
"http_request": {
"uri": "http://localhost:8082",
"method": "POST"
}
},
"type": "HTTP"
}
]
}
```
</TabItem>

<TabItem value="Java" label="Java">
This is a banana 🍌
</TabItem>
<TabItem value="Golang" label="Golang">
This is a banana 🍌
</TabItem>
<TabItem value="Python" label="Python">
This is a banana 🍌
</TabItem>
<TabItem value="CSharp" label="CSharp">
This is a banana 🍌
</TabItem>
<TabItem value="javascript" label="Javascript">
This is a banana 🍌
</TabItem>
<TabItem value="clojure" label="Clojure">
This is a banana 🍌
</TabItem>
</Tabs>

<details><summary>Sample Workflow</summary>
<p>

```json
{
"name": "Loop Task",
"taskReferenceName": "LoopTask",
"type": "DO_WHILE",
"inputParameters": {
"value": "${workflow.input.value}"
},
"loopCondition": "if ( ($.LoopTask['iteration'] < $.value ) || ( $.first_task['response']['body'] > 10)) { false; } else { true; }",
"loopOver": [
{
"name": "first task",
"taskReferenceName": "first_task",
"inputParameters": {
"http_request": {
"uri": "http://localhost:8082",
"method": "POST"
}
},
"type": "HTTP"
},{
"name": "second task",
"taskReferenceName": "second_task",
"inputParameters": {
"http_request": {
"uri": "http://localhost:8082",
"method": "POST"
}
},
"type": "HTTP"
}
],
"startDelay": 0,
"optional": false
}
```

The above definition will produce the following execution, assuming three executions occurred (alongside `first_task__1`, `first_task__2`, `first_task__3`, `second_task__1`, `second_task__2`, and `second_task__3`):

```json
{
"taskType": "DO_WHILE",
"outputData": {
"iteration": 3,
"1": {
"first_task": {
"response": {},
"headers": {
"Content-Type": "application/json"
}
},
"second_task": {
"response": {},
"headers": {
"Content-Type": "application/json"
}
}
},
"2": {
"first_task": {
"response": {},
"headers": {
"Content-Type": "application/json"
}
},
"second_task": {
"response": {},
"headers": {
"Content-Type": "application/json"
}
}
},
"3": {
"first_task": {
"response": {},
"headers": {
"Content-Type": "application/json"
}
},
"second_task": {
"response": {},
"headers": {
"Content-Type": "application/json"
}
}
}
}
}
```
</p>
</details>

<details><summary>Using Iteration Key​</summary>
<p>
Sometimes, you may want to use the iteration value/counter in the tasks used in the loop. In this example, an API call is made to GitHub (to the Netflix Conductor repository), but each loop increases the pagination.

```json
{
"name": "get_all_stars",
"taskReferenceName": "get_all_stars_loop_ref",
"inputParameters": {
"stargazers": "4000"
},
"type": "DO_WHILE",
"decisionCases": {},
"defaultCase": [],
"forkTasks": [],
"startDelay": 0,
"joinOn": [],
"optional": false,
"defaultExclusiveJoinTask": [],
"asyncComplete": false,
"loopCondition": "if ($.get_all_stars_loop_ref['iteration'] < Math.ceil($.stargazers/100)) { true; } else { false; }",
"loopOver": [
{
"name": "100_stargazers",
"taskReferenceName": "hundred_stargazers_ref",
"inputParameters": {
"counter": "${get_all_stars_loop_ref.output.iteration}",
"http_request": {
"uri": "https://api.github.com/repos/ntflix/conductor/stargazers?page=${get_all_stars_loop_ref.output.iteration}&per_page=100",
"method": "GET",
"headers": {
"Authorization": "token ${workflow.input.gh_token}",
"Accept": "application/vnd.github.v3.star+json"
}
}
},
"type": "HTTP",
"decisionCases": {},
"defaultCase": [],
"forkTasks": [],
"startDelay": 0,
"joinOn": [],
"optional": false,
"defaultExclusiveJoinTask": [],
"asyncComplete": false,
"loopOver": [],
"retryCount": 3
}
]
}
```

* The Loop `taskReferenceName` is "get_all_stars_loop_ref".
* In the `loopCondition`, the term `$.get_all_stars_loop_ref['iteration']` is used.
* In tasks embedded in the loop, `${get_all_stars_loop_ref.output.iteration}` is used. In this case, it defines which page of results the API should return.

</p>
</details>

<details><summary>Order Fulfillment</summary>
<p>

[Order Fulfillment](https://orkes.io/content/docs/codelab/orderfulfillment5_5#dowhile-loop): Loops through each address to create a shipping label.

</p>
</details>

<details><summary>Document Approvals</summary>
<p>

[Document Approvals](https://orkes.io/content/docs/usecases/document_approvals): Should approval be rejected, the Do/WHile loops back to the beginning for edits to the doc.
</p>
</details>
1 change: 0 additions & 1 deletion docs/operators/while.mdx

This file was deleted.