Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions cylc/flow/scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,10 @@ def __init__(self, id_: str, options: 'Values') -> None:
# {install_target: platform}
self.incomplete_ri_map: Dict[str, Dict] = {}

# This flag must be initialised to True, to compute the runahead
# limit at the start of the first main loop iteration.
self.has_updated: bool = True

async def install(self):
"""Get the filesystem in the right state to run the flow.
* Validate flowfiles
Expand Down Expand Up @@ -1618,8 +1622,13 @@ async def _main_loop(self) -> None:

tinit = time()

self.pool.compute_runahead()
self.pool.release_runahead_tasks()
if self.has_updated or self.pool.tasks_removed:
# The runahead limit might need recomputing.
self.pool.compute_runahead()
self.pool.release_runahead_tasks()
# Reset tasks_removed (this is the only use of this flag).
self.pool.tasks_removed = False

# If applicable, set stop mode or shutdown on task failure:
await self.workflow_shutdown()

Expand Down Expand Up @@ -1704,19 +1713,19 @@ async def _main_loop(self) -> None:
# List of task whose states have changed.
updated_task_list = [
t for t in self.pool.get_tasks() if t.state.is_updated]
has_updated = updated_task_list or self.is_updated
self.has_updated = bool(updated_task_list) or self.is_updated

if updated_task_list and self.is_restart_timeout_wait:
# Stop restart timeout if action has been triggered.
with suppress(KeyError):
self.timers[self.EVENT_RESTART_TIMEOUT].stop()
self.is_restart_timeout_wait = False

if has_updated or self.data_store_mgr.updates_pending:
if self.has_updated or self.data_store_mgr.updates_pending:
# Update the datastore.
await self.update_data_structure()

if has_updated:
if self.has_updated:
if not self.is_reloaded and self.is_stalled:
# (A reload cannot un-stall workflow by itself)
self.is_stalled = False
Expand Down Expand Up @@ -1754,7 +1763,7 @@ async def _main_loop(self) -> None:
)
)

if not has_updated and not self.stop_mode:
if not self.has_updated and not self.stop_mode:
# Has the workflow stalled?
self.check_workflow_stalled()

Expand Down
30 changes: 15 additions & 15 deletions cylc/flow/task_pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,25 +431,25 @@ def compute_runahead(self, force=False) -> bool:
)
else:
# Find the earliest point with incomplete tasks.
for point, itasks in sorted(self.get_tasks_by_point().items()):
# All n=0 tasks are incomplete by definition, but Cylc 7
# ignores failed ones (it does not ignore submit-failed!).
if (
cylc.flow.flags.cylc7_back_compat and
all(
itask.state(TASK_STATUS_FAILED)
for itask in itasks
)
):
continue
base_point = point
break
if cylc.flow.flags.cylc7_back_compat:
for point, itasks in sorted(self.get_tasks_by_point().items()):
# All n=0 tasks are incomplete by definition, but Cylc 7
# ignores failed ones (it does not ignore submit-failed!).
if (
all(
itask.state(TASK_STATUS_FAILED)
for itask in itasks
)
):
continue
base_point = point
break
else:
base_point = min(self.active_tasks)

if base_point is None:
return False

LOG.debug(f"Runahead: base point {base_point}")

if self._prev_runahead_base_point is None:
self._prev_runahead_base_point = base_point

Expand Down
Loading