@@ -1888,8 +1888,8 @@ relies on :term:`optional outputs <optional output>` and is called *branching*.
1888
1888
1889
1889
Cylc 8 does not need suicide triggers for branching.
1890
1890
1891
- Basic Example
1892
- ^^^^^^^^^^^^^
1891
+ Basic Example (A Switch)
1892
+ ^^^^^^^^^^^^^^^^^^^^^^^^
1893
1893
1894
1894
Here Cylc will follow one of two "branches" depending on the outcome of task ``b ``:
1895
1895
@@ -1938,6 +1938,18 @@ Note the last line of the graph ``c | r => d`` allows the graph to
1938
1938
continue on to ``d `` regardless of the path taken. This is an :term: `artificial
1939
1939
dependency `.
1940
1940
1941
+ This is a simple example of a "switch" pattern, the task ``b `` being the switch
1942
+ in this case, the ``succeeded `` / ``failed `` outputs deciding which pathway
1943
+ through the graph the workflow will follow. We can use outputs besides
1944
+ ``succeeded `` / ``failed `` to achieve this and can have any number of branches,
1945
+ see the
1946
+ :ref: `three-way switch example <user_guide.graph_branching.three_way_switch >`
1947
+ for more details.
1948
+
1949
+
1950
+ Recovery Tasks
1951
+ ^^^^^^^^^^^^^^
1952
+
1941
1953
Branching is often used for automatic failure recovery. Here's a simple
1942
1954
example:
1943
1955
@@ -1976,6 +1988,108 @@ A more realistic example might have several tasks on each branch. The
1976
1988
``bar ``, but configured differently to avoid the failure.
1977
1989
1978
1990
1991
+ Flaky Pipelines
1992
+ ^^^^^^^^^^^^^^^
1993
+
1994
+ Another pattern for using optional outputs is to assemble chains (or pipelines)
1995
+ of tasks where the chain is terminated on task failure.
1996
+
1997
+ Here's a simple example:
1998
+
1999
+ .. code-block :: cylc-graph
2000
+
2001
+ a? => b? => c?
2002
+
2003
+ .. digraph :: Example
2004
+ :align: center
2005
+
2006
+ a -> b [label="if a:succeeded", fontcolor="green"]
2007
+ b -> c [label="if b:succeeded", fontcolor="green"]
2008
+
2009
+ In Python, we might write this control flow like so:
2010
+
2011
+ .. code-block :: python
2012
+
2013
+ if a():
2014
+ if b():
2015
+ c()
2016
+
2017
+ Sometimes we might like to have a task at the end of the chain that runs no
2018
+ matter the outcome.
2019
+
2020
+ .. code-block :: cylc-graph
2021
+
2022
+ a? => b? => c?
2023
+
2024
+ a:fail? | b:fail? | c:finish => end
2025
+
2026
+ Note, ``:finish `` is shorthand for ``:succeed? | :fail? ``, so this can be
2027
+ re-written as:
2028
+
2029
+ .. code-block :: cylc-graph
2030
+
2031
+ a? => b? => c?
2032
+
2033
+ a:fail? | b:fail? | (c? | c:fail?) => end
2034
+
2035
+ .. digraph :: Example
2036
+ :align: center
2037
+
2038
+ a -> b -> c
2039
+
2040
+ a -> end [arrowhead="empty", style="dashed"]
2041
+ b -> end [arrowhead="empty", style="dashed"]
2042
+ c -> end [arrowhead="empty", style="dashed"]
2043
+
2044
+ This arrangement may be useful for collating the results of parallel chains:
2045
+
2046
+ .. code-block :: cylc-graph
2047
+
2048
+ a<x>? => b<x>? => c<x>?
2049
+
2050
+ a<x>:fail? | b<x>:fail? | (c<x>? | c<x>:fail?) => end<x>
2051
+
2052
+ end<x> => collate
2053
+
2054
+ .. digraph :: Example
2055
+ :align: center
2056
+
2057
+ subgraph cluster_1 {
2058
+ label = "x=1"
2059
+ style = "dashed"
2060
+
2061
+ a_1 -> b_1 -> c_1
2062
+
2063
+ a_1 -> end_1 [arrowhead="empty", style="dashed"]
2064
+ b_1 -> end_1 [arrowhead="empty", style="dashed"]
2065
+ c_1 -> end_1 [arrowhead="empty", style="dashed"]
2066
+ }
2067
+ subgraph cluster_2 {
2068
+ label = "x=2"
2069
+ style = "dashed"
2070
+
2071
+ a_2 -> b_2 -> c_2
2072
+
2073
+ a_2 -> end_2 [arrowhead="empty", style="dashed"]
2074
+ b_2 -> end_2 [arrowhead="empty", style="dashed"]
2075
+ c_2 -> end_2 [arrowhead="empty", style="dashed"]
2076
+
2077
+ }
2078
+ subgraph cluster_3 {
2079
+ label = "x=3"
2080
+ style = "dashed"
2081
+
2082
+ a_3 -> b_3 -> c_3
2083
+
2084
+ a_3 -> end_3 [arrowhead="empty", style="dashed"]
2085
+ b_3 -> end_3 [arrowhead="empty", style="dashed"]
2086
+ c_3 -> end_3 [arrowhead="empty", style="dashed"]
2087
+ }
2088
+
2089
+ end_1 -> collate
2090
+ end_2 -> collate
2091
+ end_3 -> collate
2092
+
1979
2093
Dependencies With Multiple Optional Outputs
1980
2094
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1981
2095
@@ -2078,6 +2192,8 @@ combination of success/failure for the two tasks:
2078
2192
Try editing the ``script `` in this example to see which tasks are run.
2079
2193
2080
2194
2195
+ .. _user_guide.graph_branching.three_way_switch :
2196
+
2081
2197
Custom Outputs
2082
2198
^^^^^^^^^^^^^^
2083
2199
0 commit comments