From 4ad1088e730984f85d5fc7855b87d9cb3c3ad1a0 Mon Sep 17 00:00:00 2001 From: Oliver Sanders Date: Thu, 7 Nov 2024 15:05:21 +0000 Subject: [PATCH 1/2] document graph branching with multiple optional outputs --- .../writing-workflows/scheduling.rst | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/src/user-guide/writing-workflows/scheduling.rst b/src/user-guide/writing-workflows/scheduling.rst index f69033e611..d6080debf7 100644 --- a/src/user-guide/writing-workflows/scheduling.rst +++ b/src/user-guide/writing-workflows/scheduling.rst @@ -1909,6 +1909,108 @@ A more realistic example might have several tasks on each branch. The ``bar``, but configured differently to avoid the failure. +Dependencies With Multiple Optional Outputs +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +We might have a task that depends on multiple optional outputs. + +For example, this workflow is like the "recovery task" example above, but in +this case we only want to run the recover task if both of the upstream tasks +fail. + +.. digraph:: Example + :align: center + + rankdir = "LR" + + one -> run_if_both_fail [label=":fail?", color="red", "fontcolor"="red"] + two -> run_if_both_fail [label=":fail?", color="red", "fontcolor"="red"] + + one -> always_run [label=":finish", color="orange", "fontcolor"="orange"] + two -> always_run [label=":finish", color="orange", "fontcolor"="orange"] + + subgraph cluster_1 { + label = "one:failed AND two:failed" + color = "red" + fontcolor = "red" + style = "dashed" + + run_if_both_fail + } + + subgraph cluster_2 { + label = "both tasks finished" + color = "orange" + fontcolor = "orange" + style = "dashed" + + always_run + } + +We might try to write the graph like so: + +.. code-block:: cylc-graph + + # run irrespective of whether the tasks succeed or fail + one:finish & two:finish => always_run + + # run if both tasks fail <-- ERROR + one:fail? & two:fail? => run_if_both_fail + +However, there is a problem with this. + +1. If both tasks fail, then ``run_if_both_fail`` will run. +2. If both tasks succeed, then ``run_if_both_fail`` will not run. +3. If one task succeeds and the other fails, then the task ``run_if_both_fail`` + will be left with one satisfied and one unsatisfied dependency. This will + cause the workflow to :term:`stall`. + +To prevent the workflow from stalling in the third case, it is necessay to use +:term:`suicide triggers ` to remove the task +``run_if_both_fail``. + +.. code-block:: cylc-graph + + # run irrespective of whether the tasks succeed or fail + one:finish & two:finish => always_run + + # run if both tasks fail + one:fail? & two:fail? => run_if_both_fail + one:succeeded? | two:succeeded? => !run_if_both_fail + +Here's an example workflow showing how to trigger tasks with each possible +combination of success/failre for the two tasks: + +.. code-block:: cylc + + [scheduler] + allow implicit tasks = True + + [scheduling] + [[graph]] + R1 = """ + one:finish & two:finish => always_run + + one:succeeded? | two:succeeded? => run_if_at_least_one_succeeds + + one:failed? | two:failed? => run_if_at_least_one_fails + + one:succeeded? & two:succeeded? => run_if_both_succeed + one:failed? | two:failed? => !run_if_both_succeed + + one:fail? & two:fail? => run_if_both_fail + one:succeeded? | two:succeeded? => !run_if_both_fail + """ + + [runtime] + [[one]] + script = true + [[two]] + script = false + +Try editing the ``script`` in this example to see which tasks are run. + + Custom Outputs ^^^^^^^^^^^^^^ From 4838dade77472bead157b1380d500e095587e603 Mon Sep 17 00:00:00 2001 From: Oliver Sanders Date: Fri, 8 Nov 2024 10:05:12 +0000 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Hilary James Oliver --- src/user-guide/writing-workflows/scheduling.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/user-guide/writing-workflows/scheduling.rst b/src/user-guide/writing-workflows/scheduling.rst index d6080debf7..9e6c280da2 100644 --- a/src/user-guide/writing-workflows/scheduling.rst +++ b/src/user-guide/writing-workflows/scheduling.rst @@ -1965,7 +1965,7 @@ However, there is a problem with this. will be left with one satisfied and one unsatisfied dependency. This will cause the workflow to :term:`stall`. -To prevent the workflow from stalling in the third case, it is necessay to use +To prevent the workflow from stalling in the third case, it is necessary to use :term:`suicide triggers ` to remove the task ``run_if_both_fail``. @@ -1979,7 +1979,7 @@ To prevent the workflow from stalling in the third case, it is necessay to use one:succeeded? | two:succeeded? => !run_if_both_fail Here's an example workflow showing how to trigger tasks with each possible -combination of success/failre for the two tasks: +combination of success/failure for the two tasks: .. code-block:: cylc