Skip to content

Rewrite optional outputs doc.#879

Merged
oliver-sanders merged 1 commit intocylc:masterfrom
hjoliver:optional-outputs-tweak
Sep 30, 2025
Merged

Rewrite optional outputs doc.#879
oliver-sanders merged 1 commit intocylc:masterfrom
hjoliver:optional-outputs-tweak

Conversation

@hjoliver
Copy link
Member

Goes with cylc/cylc-flow#6999

Best to look at the rendered result, not diffs.

Requirements check-list

  • I have read CONTRIBUTING.md and added my name as a Code Contributor.

@hjoliver hjoliver self-assigned this Sep 30, 2025
@hjoliver hjoliver added this to the 8.6.x milestone Sep 30, 2025
Copy link
Member

@wxtim wxtim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's fine. I've added some suggestions.

Comment on lines +30 to +32
The left side of a dependency arrow shows a logical combination of one or more task
outputs, and the right side shows which tasks to trigger when those outputs get
completed:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should definately be two sentences.

Perhaps

Suggested change
The left side of a dependency arrow shows a logical combination of one or more task
outputs, and the right side shows which tasks to trigger when those outputs get
completed:
The left side of a dependency arrow shows a logical combination of one or more task outputs. When those outputs are complete the right side shows which tasks to trigger.

.. code-block:: cylc-graph

# baz will not be run until both foo and bar have succeeded
# run baz when both foo and bar have succeeded
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that sentence order matching time and logic order makes this easier to read.

However you can argue that framing the sentence in a different order may help people with different brains.

Suggested change
# run baz when both foo and bar have succeeded
# When foo AND bar have succeeded, run baz

Comment on lines +41 to +42
However, the ``:succeeded`` output is so important that Cylc allows a plain task name on
the left as shorthand:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that the first sentence is necessary.

Suggested change
However, the ``:succeeded`` output is so important that Cylc allows a plain task name on
the left as shorthand:
Requiring the ``:succeeded`` output is a sensible default. Cylc uses a task name without
an explicit output as a shorthand for ``:succeeded``:


.. code-block:: cylc-graph

# run baz when both foo and bar have succeeded
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# run baz when both foo and bar have succeeded
# When both foo AND bar have succeeded, run baz

Comment on lines +50 to +51
(Task outputs can appear on the right of a dependency as well, in which case the
expression declares task optionality as well as triggering - see below for more).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(Task outputs can appear on the right of a dependency as well, in which case the
expression declares task optionality as well as triggering - see below for more).
(Task outputs can appear on the right of a dependency, in which case the
expression declares task optionality as well as triggering - see below for more).
Suggested change
(Task outputs can appear on the right of a dependency as well, in which case the
expression declares task optionality as well as triggering - see below for more).
.. seealso::
Task outputs can appear on the right of a dependency, in which case the
expression declares task optionality as well as triggering - see
:ref:`explict_outputs_on_the_right`.

Comment on lines +1634 to +1635
:term:`Task outputs <task output>` can be :term:`required <required output>`,
by default; or :term:`optional <optional output>`, if marked with ``?``.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
:term:`Task outputs <task output>` can be :term:`required <required output>`,
by default; or :term:`optional <optional output>`, if marked with ``?``.
:term:`Task outputs <task output>` can be :term:`required <required output>`,
by default; or :term:`optional <optional output>`.
Outputs are made optional by the addition of ``?`` in the graph.

Comment on lines +1722 to +1724
Optional outputs do not alter triggering behaviour, they just tell the
scheduler what to do with the task if it does not complete the output
at runtime.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that you might be trying to say:

Suggested change
Optional outputs do not alter triggering behaviour, they just tell the
scheduler what to do with the task if it does not complete the output
at runtime.
A required output tells the scheduler that failure to emit that output will cause a stall.
An optional output tells that scheduler that failure to emit that output need not cause a stall.
It does not alter triggering behaviour.

I'm not sure about my alternative. But I think that you should say what the scheduler does with the information.

Copy link
Member Author

@hjoliver hjoliver Oct 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've already explained above this what the scheduler does with incomplete outputs.

Here I'm primarily trying to emphasize that the triggering is exactly the same in both cases, which is commonly misunderstood by users.

Then I also go on to (re)explain just below exactly what difference it does make.

However, I'll try to rephrase this a bit - see what you think in the follow-up PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I'm rethinking this ... maybe it's not helpful to explain it in that way.

In a sense an optional output on the left does make the triggering "optional", which is arguably "affecting triggering"...


foo:x? => bar # foo:x is optional

The only difference is that in the first case ``foo`` will be retained as an
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

retained?

Suggested change
The only difference is that in the first case ``foo`` will be retained as an
The only difference is that in the first case ``foo`` will be retained in the task pool as an

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(In the "n=0 window" these days, but yes).

Comment on lines +1760 to +1761
Secondly, success and failure of a task are mutually exclusive opposites so
either one or the other can be required or they must both be optional:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Secondly, success and failure of a task are mutually exclusive opposites so
either one or the other can be required or they must both be optional:
Tasks **cannot** succeed **and** fail! Only one can be required. Both may be optional:

Custom Outputs
^^^^^^^^^^^^^^

If a task generates multiple related custom outputs they should all be required
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be a bit misleading - it's totally right if you want to have

model:first_hour => standard_post_proc1
model:second_hour => standard_post_proc2

or

model:unstable? => high_detail_convection
model:stable? => fog_model

but what if you have both?

I think what this boils downs to is "please think carefully about whether custom outputs should stall the workflow if not emitted".

Copy link
Member

@oliver-sanders oliver-sanders left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to merge this now so we can get the release going, @wxtim might want to raise suggestions as a follow-up PR.

@oliver-sanders oliver-sanders merged commit ad61cb1 into cylc:master Sep 30, 2025
1 check passed
@hjoliver hjoliver deleted the optional-outputs-tweak branch October 1, 2025 01:14
wxtim added a commit that referenced this pull request Oct 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants