Skip to content

Commit fb9bacf

Browse files
authored
Adding continueAs prop to end definitions (#446) (#451)
* Adding continueAs prop to end definitions Signed-off-by: Tihomir Surdilovic <[email protected]> * fix link Signed-off-by: Tihomir Surdilovic <[email protected]> * updated roadmap Signed-off-by: Tihomir Surdilovic <[email protected]> * added section on sub-workflows and continueAs Signed-off-by: Tihomir Surdilovic <[email protected]>
1 parent 3954c8d commit fb9bacf

File tree

3 files changed

+117
-4
lines changed

3 files changed

+117
-4
lines changed

roadmap/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ _Status description:_
4545
| ✔️| Added Rate Limiting extension | [spec doc](../specification.md) |
4646
| ✔️| Update ForEach state - adding sequential exec option and batch size for parallel option | [spec doc](../specification.md) |
4747
| ✔️| Update to error handling and retries. Retries are now per action rather than per state. Added option of automatic retries for actions | [spec doc](../specification.md) |
48+
| ✔️| Added "continueAs" property to end definitions | [spec doc](https://github.com/serverlessworkflow/specification/blob/0.6.x/specification.md) |
4849

4950
## Release Version 0.6
5051

schema/workflow.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,43 @@
250250
}
251251
]
252252
},
253+
"continueasdef": {
254+
"oneOf": [
255+
{
256+
"type": "string",
257+
"description": "Unique id of the workflow to be continue execution as. Entire state data is passed as data input to next execution",
258+
"minLength": 1
259+
},
260+
{
261+
"type": "object",
262+
"properties": {
263+
"workflowId": {
264+
"type": "string",
265+
"description": "Unique id of the workflow to continue execution as"
266+
},
267+
"version": {
268+
"type": "string",
269+
"description": "Version of the workflow to continue execution as",
270+
"minLength": 1
271+
},
272+
"data": {
273+
"type": [
274+
"string",
275+
"object"
276+
],
277+
"description": "If string type, an expression which selects parts of the states data output to become the workflow data input of continued execution. If object type, a custom object to become the workflow data input of the continued execution"
278+
},
279+
"workflowExecTimeout": {
280+
"$ref": "timeouts.json#/definitions/workflowExecTimeout",
281+
"description": "Workflow execution timeout to be used by the workflow continuing execution. Overwrites any specific settings set by that workflow"
282+
}
283+
},
284+
"required": [
285+
"workflowId"
286+
]
287+
}
288+
]
289+
},
253290
"transition": {
254291
"oneOf": [
255292
{
@@ -1825,6 +1862,9 @@
18251862
"type": "boolean",
18261863
"default": false,
18271864
"description": "If set to true, triggers workflow compensation. Default is false"
1865+
},
1866+
"continueAs": {
1867+
"$ref": "#/definitions/continueasdef"
18281868
}
18291869
},
18301870
"additionalProperties": false,

specification.md

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@
8686
+ [Compensation Execution Details](#compensation-execution-details)
8787
+ [Compensation and Active States](#compensation-and-active-states)
8888
+ [Unrecoverable errors during compensation](#unrecoverable-errors-during-compensation)
89+
* [Continuing as a new Execution](#continuing-as-a-new-execution)
90+
+ [ContinueAs in sub workflows](#continueas-in-sub-workflows)
8991
* [Workflow Versioning](#workflow-versioning)
9092
* [Workflow Constants](#workflow-constants)
9193
* [Workflow Secrets](#workflow-secrets)
@@ -4616,8 +4618,8 @@ Can be either `boolean` or `object` type. If type boolean, must be set to `true`
46164618
"end": true
46174619
```
46184620

4619-
In this case it's assumed that the `terminate` property has its default value of `false`, and the `produceEvents` and
4620-
`compensate` properties are not defined.
4621+
In this case it's assumed that the `terminate` property has its default value of `false`, and the `produceEvents`,
4622+
`compensate`, and `continueAs` properties are not defined.
46214623

46224624
If the end definition is of type `object`, it has the following structure:
46234625

@@ -4626,6 +4628,7 @@ If the end definition is of type `object`, it has the following structure:
46264628
| terminate | If true, terminates workflow instance execution | boolean | no |
46274629
| produceEvents | Array of [producedEvent](#ProducedEvent-Definition) definitions. Defines events that should be produced. | array | no |
46284630
| [compensate](#Workflow-Compensation) | If set to `true`, triggers workflow compensation before workflow execution completes. Default is `false` | boolean | no |
4631+
| [continueAs](#continuing-as-a-new-execution) | Defines that current workflow execution should stop, and execution should continue as a new workflow instance of the provided id | string or object | no |
46294632

46304633
<details><summary><strong>Click to view example definition</strong></summary>
46314634
<p>
@@ -4667,8 +4670,8 @@ produceEvents:
46674670

46684671
End definitions are used to explicitly define execution completion of a workflow instance or workflow execution path.
46694672
A workflow definition must include at least one [workflow state](#Workflow-States).
4670-
Note that [Switch states](#Switch-State) cannot declare to be workflow end states. Switch states must end
4671-
their execution followed by a transition another workflow state, given their conditional evaluation.
4673+
Note that [Switch states](#Switch-State) cannot declare to be workflow end states. Their conditions however can
4674+
define a stop of workflow execution.
46724675

46734676
The `terminate` property, if set to `true`, completes the workflow instance execution, this any other active
46744677
execution paths.
@@ -4683,6 +4686,15 @@ is if workflow execution reaches a state that defines an end definition with `te
46834686
or, if the [`workflowExecTimeout`](#Workflow-Timeouts) property is defined, the time defined in its `interval`
46844687
is reached.
46854688

4689+
The [compensate](#Workflow-Compensation) property defines that workflow compensation should be performed before the workflow
4690+
execution is completed.
4691+
4692+
The [continueAs](#Continuing as a new Execution) property defines that the current workflow instance should stop its execution,
4693+
and worklow execution should continue as a new instance of a new workflow.
4694+
When defined, it should be assumed that `terminate` is `true`. If `continueAs` is defined, and `terminate` is explicitly
4695+
set to false, runtimes should report this to users. Producing events, and compensation should still be performed (if defined)
4696+
before the workflow execution is stopped, and continued as a new workflow instance with the defined workflow id.
4697+
46864698
##### ProducedEvent Definition
46874699

46884700
| Parameter | Description | Type | Required |
@@ -5744,6 +5756,66 @@ States that are marked as `usedForCompensation` can define [error handling](#Wor
57445756
(errors not explicitly handled),
57455757
workflow execution should be stopped, which is the same behavior as when not using compensation as well.
57465758

5759+
### Continuing as a new Execution
5760+
5761+
In some cases our workflows are deployed and executed on runtimes and/or cloud platforms that expose some
5762+
execution limitations such as finite execution duration, finite number of workflow transitions, etc.
5763+
Some runtimes, especially when dealing with stateful workflow orchestrations have a finite limit of
5764+
execution history log sizes, meaning that once a long-running workflow reaches these limits workflow executions is
5765+
likely to be forced to stop before reaching its completion. This can result in unexpected issues, especially with
5766+
mission-critical workflows.
5767+
5768+
For those cases, the Serverless Workflow DSL provides a way to explicitly define stopping the current workflow
5769+
instance execution, and starting a new one (for the same workflow id or a different one).
5770+
This can be done via the [end definitions](#end-definition) `continueAs` property.
5771+
5772+
The end definitions `continueAs` can be either of type `string` or `object`.
5773+
If string type, it contains the unique workflow id of the workflow that the execution should continue as, for example:
5774+
5775+
5776+
```json
5777+
{
5778+
"end": {
5779+
"continueAs": "myworkflowid"
5780+
}
5781+
}
5782+
```
5783+
5784+
Defining this should stop the current workflow execution, and continue execution as a new workflow instance of the
5785+
workflow which defines the workflow id of "myworkflowid". The state data where this is define should
5786+
become the workflow data input of the workflow that is continuing the current workflow execution.
5787+
5788+
Note that any defined `produceEvents` and `compensate` definitions should be honored before `continueAs` is applied.
5789+
5790+
If `object` type, the `continueAs` property has the following properties:
5791+
5792+
| Parameter | Description | Type | Required |
5793+
| --- | --- | --- | --- |
5794+
| workflowId | Unique id of the workflow to continue execution as. | string | yes |
5795+
| version | Version of the workflow to continue execution as. | string | no |
5796+
| data | If string type, a workflow expression which selects parts of the states data output to become the workflow data input of continued execution. If object type, a custom object to become the workflow data input of the continued execution. | string or object | no |
5797+
| [`workflowExecTimeout`](#Workflow-Timeouts) | Workflow execution timeout to be used by the workflow continuing execution. Overwrites any specific settings set by that workflow. | string or object | no |
5798+
5799+
Continuing execution with `continueAs` can also be used inside sub-workflow executions, which brings its next use case.
5800+
5801+
#### ContinueAs in sub workflows
5802+
5803+
Workflows can invoke sub-workflows during their execution. In Serverless Workflow DSL, sub-workflows are invoked
5804+
similarly to other function types via the [SubFlowRef Definition](#SubFlowRef-Definition)
5805+
in workflow states [Action](#Action-Definition) definitions.
5806+
5807+
Just like "parent" workflows, sub-workflow can also be long-running, and can run into the same type of runtime/serverless platform
5808+
limitations as previously discussed. As such they can also use `continueAs` to stop their current execution and continue it as
5809+
a new one of the same or different workflow id.
5810+
5811+
Note that when a sub-workflow is invoked it can produce a result that is then merged into the parent workflow state data.
5812+
This may bring up a question as to what happens when a sub-workflow calls `continueAs` in terms of what is returned as
5813+
result to of its invocation by the parent workflow.
5814+
5815+
No matter how many times sub-workflow may use `continueAs`, to the parent workflow it should be as a single invocation is performed,
5816+
meaning that the results of the last sub-workflow invocation (triggered by `continueAs`) should be used as the
5817+
data returned by the invocation of the sub-workflow to the parent workflow.
5818+
57475819
### Workflow Versioning
57485820

57495821
In any application, regardless of size or type, one thing is for sure: changes happen.

0 commit comments

Comments
 (0)