Skip to content

Commit

Permalink
startup and shutdown graphs; needs tidying
Browse files Browse the repository at this point in the history
  • Loading branch information
hjoliver committed Sep 22, 2022
1 parent ce00060 commit a53ac82
Show file tree
Hide file tree
Showing 6 changed files with 279 additions and 39 deletions.
18 changes: 17 additions & 1 deletion cylc/flow/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 26,10 @@
structures.
"""

# TODO NOCYCLE GRAPHS:
# - graph and check-circular for startup and shutdown
# - validation should disallow reuse of task names in the 3 sections

from contextlib import suppress
from copy import copy
from fnmatch import fnmatchcase
Expand Down Expand Up @@ -54,13 58,15 @@
get_sequence, get_sequence_cls, init_cyclers, get_dump_format,
INTEGER_CYCLING_TYPE, ISO8601_CYCLING_TYPE
)
from cylc.flow.cycling.nocycle import NOCYCLE_GRAPHS, NocycleSequence
from cylc.flow.id import Tokens
from cylc.flow.cycling.integer import IntegerInterval
from cylc.flow.cycling.iso8601 import ingest_time, ISO8601Interval
from cylc.flow.exceptions import (
CylcError,
WorkflowConfigError,
IntervalParsingError,
SequenceParsingError,
TaskDefError,
ParamExpandError,
InputError
Expand Down Expand Up @@ -269,6 275,7 @@ def __init__(
self.start_point: 'PointBase'
self.stop_point: Optional['PointBase'] = None
self.final_point: Optional['PointBase'] = None
self.nocycle_sequences: Set['NocycleSequence'] = set()
self.sequences: List['SequenceBase'] = []
self.actual_first_point: Optional['PointBase'] = None
self._start_point_for_actual_first_point: Optional['PointBase'] = None
Expand Down Expand Up @@ -2054,6 2061,12 @@ def load_graph(self):
for section, graph in sections:
try:
seq = get_sequence(section, icp, fcp)
except SequenceParsingError:
if section in NOCYCLE_GRAPHS:
seq = NocycleSequence(section)
self.nocycle_sequences.add(seq)
else:
raise
except (AttributeError, TypeError, ValueError, CylcError) as exc:
if cylc.flow.flags.verbosity > 1:
traceback.print_exc()
Expand All @@ -2063,7 2076,10 @@ def load_graph(self):
if isinstance(exc, CylcError):
msg = ' %s' % exc.args[0]
raise WorkflowConfigError(msg)
self.sequences.append(seq)

else:
self.sequences.append(seq)

parser = GraphParser(
family_map,
self.parameters,
Expand Down
6 changes: 5 additions & 1 deletion cylc/flow/cycling/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 342,11 @@ def TYPE_SORT_KEY(self) -> int:
@classmethod
@abstractmethod # Note: stacked decorator not strictly enforced in Py2.x
def get_async_expr(cls, start_point=0):
"""Express a one-off sequence at the initial cycle point."""
"""Express a one-off sequence at the initial cycle point.
Note "async" has nothing to do with asyncio. It was a (bad)
name for one-off (non-cycling) graphs in early Cylc versions.
"""
pass

@abstractmethod
Expand Down
87 changes: 87 additions & 0 deletions cylc/flow/cycling/nocycle.py
Original file line number Diff line number Diff line change
@@ -0,0 1,87 @@
# THIS FILE IS PART OF THE CYLC WORKFLOW ENGINE.
# Copyright (C) NIWA & British Crown (Met Office) & Contributors.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""
No-cycle logic for isolated start-up and shutdown graphs.
"""

NOCYCLE_STARTUP = "startup"
NOCYCLE_SHUTDOWN = "shutdown"

NOCYCLE_GRAPHS = (
NOCYCLE_STARTUP,
NOCYCLE_SHUTDOWN
)


class NocyclePoint:
"""A string-valued no-cycle point."""

def __init__(self, value: str) -> None:
if value not in NOCYCLE_GRAPHS:
raise ValueError(f"Illegal Nocycle value {value}")
self.value = value

def __hash__(self):
return hash(self.value)

def __eq__(self, other):
return other.value == self.value

def __le__(self, other):
return str(other) == str(self.value)

def __lt__(self, other):
return False

def __gt__(self, other):
return False

def __str__(self):
return self.value


class NocycleSequence:
"""A no-cycle sequence is just a point."""

def __init__(self, dep_section, p_context_start=None, p_context_stop=None):
"""blah"""
self.point = NocyclePoint(dep_section)

def is_valid(self, point):
"""Is point on-sequence and in-bounds?"""
return True

def get_first_point(self, point):
"""blah"""
return None

def get_next_point_on_sequence(self, point):
"""blah"""
return self.point

def __hash__(self):
return hash(str(self.point))

def __eq__(self, other):
return other.point == self.point

def __str__(self):
return str(self.point)


NOCYCLE_STARTUP_SEQUENCE = NocycleSequence(NOCYCLE_STARTUP)
NOCYCLE_SHUTDOWN_SEQUENCE = NocycleSequence(NOCYCLE_SHUTDOWN)
Loading

0 comments on commit a53ac82

Please sign in to comment.