Skip to content

Commit 8d1c25d

Browse files
committed
While, Do-while loop implementation for fetching paginated data from an API
Signed-off-by: Nyamath Shaik <nyamath.shaik@uipath.com>
1 parent 422410d commit 8d1c25d

File tree

3 files changed

+142
-1
lines changed

3 files changed

+142
-1
lines changed

dsl-reference.md

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
- [Switch](#switch)
3030
- [Try](#try)
3131
- [Wait](#wait)
32+
- [While](#while)
3233
+ [Flow Directive](#flow-directive)
3334
+ [Lifecycle Events](#lifecycle-events)
3435
- [Workflow Lifecycle Events](#workflow-lifecycle-events)
@@ -274,6 +275,7 @@ The Serverless Workflow DSL defines a list of [tasks](#task) that **must be** su
274275
- [Set](#set), used to dynamically set the [workflow](#workflow)'s data during the its execution.
275276
- [Try](#try), used to attempt executing a specified [task](#task), and to handle any resulting [errors](#error) gracefully, allowing the [workflow](#workflow) to continue without interruption.
276277
- [Wait](#wait), used to pause or wait for a specified duration before proceeding to the next task.
278+
- [While](#while), used to iterate over a collection of items based on a condition, supporting both pre-test (while) and post-test (do-while) loops.
277279
278280
#### Properties
279281
@@ -781,7 +783,7 @@ Provides the capability to execute external [containers](#container-process), [s
781783
| run.script | [`script`](#script-process) | `no` | The definition of the script to run.<br>*Required if `container`, `shell` and `workflow` have not been set.* |
782784
| run.shell | [`shell`](#shell-process) | `no` | The definition of the shell command to run.<br>*Required if `container`, `script` and `workflow` have not been set.* |
783785
| run.workflow | [`workflow`](#workflow-process) | `no` | The definition of the workflow to run.<br>*Required if `container`, `script` and `shell` have not been set.* |
784-
| await | `boolean` | `no` | Determines whether or not the process to run should be awaited for.<br>*When set to `false`, the task cannot wait for the process to complete and thus cannot output the processs result. In this case, it should simply output its transformed input.*<br>*Defaults to `true`.* |
786+
| await | `boolean` | `no` | Determines whether or not the process to run should be awaited for.<br>*When set to `false`, the task cannot wait for the process to complete and thus cannot output the process's result. In this case, it should simply output its transformed input.*<br>*Defaults to `true`.* |
785787
| return | `string` | `no` | Configures the output of the process.<br>*Supported values are:*<br>*- `stdout`: Outputs the content of the process **STDOUT**.*<br>*- `stderr`: Outputs the content of the process **STDERR**.*<br>*- `code`: Outputs the process's **exit code**.*<br>*- `all`: Outputs the **exit code**, the **STDOUT** content and the **STDERR** content, wrapped into a new [processResult](#process-result) object.*<br>*- `none`: Does not output anything.*<br>*Defaults to `stdout`.* |
786788

787789
##### Examples
@@ -1146,6 +1148,66 @@ do:
11461148
seconds: 10
11471149
```
11481150

1151+
#### While
1152+
1153+
Enables iterative execution of tasks based on a condition, supporting both pre-test (while) and post-test (do-while) loops. This task type is essential for scenarios requiring repetitive execution until a specific condition is met.
1154+
1155+
##### Properties
1156+
1157+
| Name | Type | Required | Description|
1158+
|:--|:---:|:---:|:---|
1159+
| while | `string` | `yes` | A [runtime expression](dsl.md#runtime-expressions) that represents the condition that must be met for the iteration to continue. |
1160+
| postConditionCheck | `boolean` | `no` | Determines whether the condition is evaluated after (do-while) or before (while) executing the task.<br>*If set to `true`, implements a do-while loop (post-test).*<br>*If set to `false`, implements a while loop (pre-test).*<br>*Defaults to `false`.* |
1161+
| maxIterations | `integer` | `no` | The maximum number of iterations allowed to prevent infinite loops.<br>*If not set, implementation-specific default limits apply.* |
1162+
| do | [`map[string, task]`](#task) | `yes` | The [task(s)](#task) to perform while the condition is true. |
1163+
1164+
##### Examples
1165+
1166+
```yaml
1167+
document:
1168+
dsl: '1.0.0'
1169+
namespace: test
1170+
name: while-example
1171+
version: '0.1.0'
1172+
do:
1173+
# While loop example (pre-test)
1174+
- fetchPaginatedData:
1175+
while: .hasNextPage == true
1176+
maxIterations: 100
1177+
do:
1178+
- fetchPage:
1179+
call: getPageData
1180+
input:
1181+
pageToken: .nextPageToken
1182+
output: .fetchedData
1183+
- accumulateData:
1184+
run: mergeResults
1185+
input:
1186+
newData: .fetchedData
1187+
existingData: .accumulatedResults
1188+
output: .accumulatedResults
1189+
1190+
# Do-while loop example (post-test)
1191+
- retryOperation:
1192+
while: .retryNeeded == true
1193+
postConditionCheck: true
1194+
maxIterations: 3
1195+
do:
1196+
- attemptOperation:
1197+
call: performOperation
1198+
output:
1199+
as: |
1200+
if .status == "failed" then
1201+
{ retryNeeded: true }
1202+
else
1203+
{ retryNeeded: false }
1204+
end
1205+
```
1206+
1207+
In the examples above:
1208+
- The first task demonstrates a while loop that fetches paginated data until there are no more pages, with a maximum of 100 iterations.
1209+
- The second task shows a do-while loop that retries an operation up to 3 times, evaluating the retry condition after each attempt.
1210+
11491211
### Flow Directive
11501212

11511213
Flow Directives are commands within a workflow that dictate its progression.

examples/while.yaml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
document:
2+
dsl: '1.0.0'
3+
namespace: test
4+
name: while-examples
5+
version: '0.1.0'
6+
7+
do:
8+
# Example of a while loop (condition evaluated before execution)
9+
- fetchPaginatedData:
10+
while: .hasNextPage == true
11+
maxIterations: 100
12+
do:
13+
- fetchPage:
14+
call: getPageData
15+
input:
16+
pageToken: .nextPageToken
17+
output: .fetchedData
18+
- accumulateData:
19+
run: mergeResults
20+
input:
21+
newData: .fetchedData
22+
existingData: .accumulatedResults
23+
output: .accumulatedResults
24+
25+
# Example of a do-while loop (condition evaluated after execution)
26+
- retryOperation:
27+
while: .retryCount < 3 && .success == false
28+
postConditionCheck: true
29+
do:
30+
- attempt:
31+
call: someOperation
32+
output:
33+
as: .success
34+
- updateRetry:
35+
set:
36+
retryCount: '${ .retryCount + 1 }'
37+
38+
# Example using iteration counter
39+
- countToMax:
40+
while: .counter < .maxValue
41+
at: iteration
42+
maxIterations: 10
43+
do:
44+
- increment:
45+
set:
46+
counter: '${ .counter + 1 }'
47+
iterations: '${ .iterations + [.iteration] }'

schema/workflow.yaml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ $defs:
213213
- $ref: '#/$defs/forkTask'
214214
- $ref: '#/$defs/emitTask'
215215
- $ref: '#/$defs/forTask'
216+
- $ref: '#/$defs/whileTask'
216217
- $ref: '#/$defs/listenTask'
217218
- $ref: '#/$defs/raiseTask'
218219
- $ref: '#/$defs/runTask'
@@ -544,6 +545,37 @@ $defs:
544545
do:
545546
$ref: '#/$defs/taskList'
546547
title: ForTaskDo
548+
whileTask:
549+
type: object
550+
$ref: '#/$defs/taskBase'
551+
title: WhileTask
552+
description: A task that enables conditional looping with support for both while and do-while behavior.
553+
required: [ while, do ]
554+
unevaluatedProperties: false
555+
properties:
556+
while:
557+
type: string
558+
title: WhileCondition
559+
description: A runtime expression that represents the condition that must be met for the iteration to continue.
560+
postConditionCheck:
561+
type: boolean
562+
title: PostConditionCheck
563+
description: Controls whether the condition is evaluated after (do-while) or before (while) executing the tasks. When true, enables do-while behavior.
564+
default: false
565+
maxIterations:
566+
type: integer
567+
title: MaxIterations
568+
description: The maximum number of iterations to perform, if any.
569+
minimum: 1
570+
at:
571+
type: string
572+
title: WhileAt
573+
description: The name of the variable used to store the index of the current iteration.
574+
default: index
575+
do:
576+
$ref: '#/$defs/taskList'
577+
title: WhileTaskDo
578+
description: The tasks to execute in each iteration.
547579
listenTask:
548580
type: object
549581
$ref: '#/$defs/taskBase'

0 commit comments

Comments
 (0)