This is an automated email from the ASF dual-hosted git repository. heneveld pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/brooklyn-docs.git
The following commit(s) were added to refs/heads/master by this push: new 8f572161 documentation for subworkflow and workflow iteration conditions 8f572161 is described below commit 8f57216161dd6cb2a90c3d2932bfbf01923d10eb Author: Alex Heneveld <a...@cloudsoft.io> AuthorDate: Thu Feb 15 16:48:59 2024 +0000 documentation for subworkflow and workflow iteration conditions --- guide/blueprints/workflow/nested-workflow.md | 47 +++++++++++++++++++++++++--- guide/blueprints/workflow/steps/steps.yaml | 20 ++++++++++-- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/guide/blueprints/workflow/nested-workflow.md b/guide/blueprints/workflow/nested-workflow.md index 19191580..ea95a74c 100644 --- a/guide/blueprints/workflow/nested-workflow.md +++ b/guide/blueprints/workflow/nested-workflow.md @@ -60,12 +60,31 @@ and its 0-indexed position. These names can be overridden with the `target_var_n Where a list is supplied, the result of the step is the list collecting the output of each sub-workflow. -If a `condition` is supplied when a list is being used, the `workflow` step will always run, -and the `condition` will be applied to entries in the list. -An example of this is included below. +If a `condition` is supplied when a list is being used, +that `condition` is applied to each entry in the list. +The `workflow` step itself will always appear to run, but might have 0 nested workflows, +and in that case will return the empty list. +If the condition is intended to block the list from being evaluated, +and should be evaluated in the containing workflow's scope, +consider using a `subworkflow` with the outer condition containing the `workflow`. +An example of this is included below, using `service.isUp` with `children`. + +### Associated Step Types The `foreach` type is a simplified variant of `workflow` when recursing over a list, -taking the same. +taking the same arguments as `workflow` but supporting a shorthand syntax where +the `target_var_name` and `target` can be specified as in `foreach VAR_NAME in TARGET`. +The `steps` are required and are run for all elements in the list. + +The `subworkflow` type is another simplified variant that does not allow any target +(so no recursing over a list and no concurrency), and which -- unlike the other workflow step types -- +shares variables with the calling workflow. All variables from the immediate containing workflow +can be accessed and updated in a `subworkflow`, and new variables defined in the `subworkflow` +are subsequently available in the outer workflow. The `steps` are required/ +A `name` is frequently given for readability, as are `condition` or `on-error` entries +to apply a condition or error-handler to the block of steps. +If no step type is defined, but `steps` are defined, this `subworkflow` step type is assumed. + #### Example @@ -85,7 +104,11 @@ apart from values specified as `input`, or with other iterations of a loop. Where it is desired to share variables across iterations, the key `reducing` can be supplied, giving a map of variable names to be shared and their initial values. -When `reducing`, the output of the workflow is this set of variables with their final values. +When `reducing`, the indicated variables are available as scratch workflow variables in the calling workflow. + +This cannot be used with `subworkflow`, as all variables are considered reduced in a `subworkflow`, +and it cannot be used with `concurrency` as that risks race conditions in updating the reduced variables. +(You can use `inputs` with both to provide new local variables.) #### Example @@ -137,6 +160,20 @@ running in batches of up to 5 but not more than a third of the children at once: - invoke-effector effector-on-children ``` +As noted above, the `condition` here is evaluated on each child. +To have it evaluated on the parent context instead, you can write: + +``` +- condition: + sensor: service.isUp + equals: true + steps: + - type: workflow + target: children + concurrency: max(1, min(33%, 5)) + steps: + - invoke-effector effector-on-children +``` ### Defining Custom Workflow Steps diff --git a/guide/blueprints/workflow/steps/steps.yaml b/guide/blueprints/workflow/steps/steps.yaml index 6a338f7f..ef4e9761 100644 --- a/guide/blueprints/workflow/steps/steps.yaml +++ b/guide/blueprints/workflow/steps/steps.yaml @@ -220,6 +220,19 @@ output: if `reducing` is specified, the final value of those variables, otherwise the output from the last step in the nested workflow or a list of such outputs if supplied a `target` list + - name: subworkflow + summary: | + A simple set of steps to run, like `workflow` but more restricted in options, + and sharing workflow variables with the containing workflow. + No `target` or `concurrency` can be specified, and all containing workflow variables are in scope, + + A `name` can be given to a block of commands to improve understandability, + A `condition` can be set on the entire block + , but not allowing a target Runs nested workflow, optionally over an indicated target. + This step type is described in more detail [here](../nested-workflow.html). + shorthand: none; this step type is implied if there is no `step` shorthand or type indicated when there are `steps` defined + input: | + - name: foreach summary: Runs nested workflow over a list using the specified variable name, equivalent to `workflow` when looping over a list shorthand: '`foreach TARGET_VAR_NAME [ in TARGET ]`' @@ -407,8 +420,11 @@ the value will be coerced to the given type, e.g. to force conversion to an integer or to a bean registered type; if the `name` contains bracketed portions, these are treated as keys in a map or positions in list to be set * `value`: the value to set - * `require`: a condition to evaluate against the sensor value while holding the lock on the sensor, - used to enable atomic operations similar to the `lock` workflow setting + * `require`: a condition to evaluate against the sensor value, + evaluated along with `value` while holding the lock on the sensor; + if the condition is not satisfied, an error is thrown and the sensor is not set, + enabling lightweight atomic check-and-set operations against the current value + without needing to use a explicit `lock` in the workflow output: the output from the previous step, or null if this is the first step - name: clear-config