@@ -1894,12 +1894,12 @@ A more realistic example might have several tasks on each branch. The
1894
1894
``bar ``, but configured differently to avoid the failure.
1895
1895
1896
1896
1897
- Message Trigger Example
1898
- ^^^^^^^^^^^^^^^^^^^^^^^
1897
+ Custom Outputs
1898
+ ^^^^^^^^^^^^^^
1899
1899
1900
- Branching is particularly powerful when using :ref: ` MessageTriggers ` (i.e.
1901
- :term: `custom outputs <custom output> `) to define multiple parallel paths in
1902
- the graph.
1900
+ Branching is particularly powerful when using
1901
+ :term: `custom outputs <custom output> ` to define alternate parallel paths in the
1902
+ graph.
1903
1903
1904
1904
In the following graph there is a task called ``showdown `` which produces one
1905
1905
of three possible custom outputs, ``good ``, ``bad `` or ``ugly ``. Cylc will follow
@@ -1961,7 +1961,7 @@ three custom outputs:
1961
1961
1962
1962
[runtime]
1963
1963
[[showdown]]
1964
- # Randomly return one of the three custom outputs.
1964
+ # Randomly return one of the three custom outputs:
1965
1965
script = """
1966
1966
SEED=$RANDOM
1967
1967
if ! (( $SEED % 3 )); then
@@ -1972,36 +1972,62 @@ three custom outputs:
1972
1972
cylc message 'The Ugly'
1973
1973
fi
1974
1974
"""
1975
+
1976
+ # Ensure that at least one of the custom outputs is produced:
1977
+ completion = succeeded and (good or bad or ugly)
1978
+
1979
+ # Register the three custom outputs:
1975
1980
[[[outputs]]]
1976
- # Register the three custom outputs.
1977
1981
good = 'The Good'
1978
1982
bad = 'The Bad'
1979
1983
ugly = 'The Ugly'
1980
1984
1985
+ Completion Expressions
1986
+ """"""""""""""""""""""
1981
1987
1982
- When using message triggers in this way there are two things to be aware of:
1988
+ .. cylc-scope :: flow.cylc[runtime][<namespace>]
1983
1989
1984
- 1. Message triggers are not exit states.
1990
+ The :cylc:conf: `completion ` configuration above is optional, it adds a basic
1991
+ validation check which ensures that at least one of the three custom outputs is
1992
+ produced when the task runs. This protects you against the possibility that
1993
+ none of the outputs are produced e.g. due to a task implementation error.
1985
1994
1986
- Custom output messages are generated *before * the task has completed, so it
1987
- can be useful to combine them with a regular trigger for safety e.g:
1995
+ If the task does not produce at least one of these three outputs, then it will
1996
+ be marked as having incomplete outputs and will be retained in a similar manner
1997
+ to if it had failed. This provides you with an opportunity to intervene to
1998
+ rectify the situation: Without intervention the workflow will :term: `stall `.
1988
1999
1989
- .. code-block :: cylc-graph
2000
+ .. cylc-scope :: flow.cylc
2001
+
2002
+ Mutually Exclusive Outputs
2003
+ """"""""""""""""""""""""""
1990
2004
1991
- # good will wait for showdown to finish before running
1992
- showdown:finish & showdown:good => good
2005
+ It is not possible to enforce mutually exclusive outputs in Cylc as
2006
+ tasks may be re-run multiple times and the outputs from previous runs
2007
+ accumulate.
1993
2008
1994
- # if showdown fails then good will not run
1995
- showdown:succeed & showdown:good => good
2009
+ E.g, this expression ensures that ** at least one ** of the three custom outputs
2010
+ is produced when the task runs:
1996
2011
1997
- 2. Whether message outputs from a single task are mutually exclusive or not
1998
- depends on the task, and the workflow should be designed accordingly.
2012
+ .. code-block :: cylc
2013
+
2014
+ completion = succeeded and (good or bad or ugly)
1999
2015
2000
- For example, the ``showdown `` task above could instead send all three
2001
- messages in succession, after writing out corresponding *good *, *bad *, and
2002
- *ugly * files.
2016
+ However, it is not possible to ensure that **only ** one of the three is
2017
+ produced.
2018
+
2019
+ Custom Output Generation Timing
2020
+ """""""""""""""""""""""""""""""
2021
+
2022
+ Custom outputs are generated *before * the task succeeds or fails. This is handy
2023
+ if you don't want downstream tasks to wait for upstream tasks to finish
2024
+ executing, e.g:
2025
+
2026
+ .. code-block :: cylc-graph
2003
2027
2004
- Check that you understand how your tasks work, if they use custom outputs.
2028
+ # run "process_file_1" as soon as the output "file_1" is completed, but
2029
+ # don't wait for "model" to finish first
2030
+ model:file_1_ready => process_file_1
2005
2031
2006
2032
2007
2033
.. _RunaheadLimit :
0 commit comments