Skip to content

Commit

Permalink
Merge pull request #3982 from MetRonnie/keyboard-interrupt
Browse files Browse the repository at this point in the history
Fix failure to shutdown on keyboard interrupt
  • Loading branch information
hjoliver authored Dec 7, 2020
2 parents a6bac41 + 7cfb0ec commit db993d5
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 20 deletions.
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@ task outputs/message triggers are now validated.
workflow in a sub-directory of a run directory (as `cylc scan` would not be
able to find it).

[#3982](https://github.com/cylc/cylc-flow/pull/3982) - Fix bug preventing
workflow from shutting down properly on a keyboard interrupt (Ctrl+C) in
Python 3.8+.

-------------------------------------------------------------------------------
## __cylc-8.0a2 (2020-07-03)__

Expand Down
38 changes: 25 additions & 13 deletions cylc/flow/scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -611,13 +611,8 @@ async def start_scheduler(self):
await self.shutdown(exc)
raise exc from None

except Exception as exc:
try:
await self.shutdown(exc)
except Exception as exc2:
# In case of exceptions in the shutdown method itself
LOG.exception(exc2)
raise exc from None
except (KeyboardInterrupt, asyncio.CancelledError, Exception) as exc:
await self.handle_exception(exc)

else:
# main loop ends (not used?)
Expand All @@ -643,9 +638,8 @@ async def run(self):
await self.configure()
await self.start_servers()
await self.log_start()
except Exception as exc:
await self.shutdown(exc)
raise
except (KeyboardInterrupt, asyncio.CancelledError, Exception) as exc:
await self.handle_exception(exc)
else:
# note start_scheduler handles its own shutdown logic
await self.start_scheduler()
Expand Down Expand Up @@ -1619,16 +1613,19 @@ async def shutdown(self, reason):
"""
if isinstance(reason, SchedulerStop):
LOG.info('Suite shutting down - %s', reason.args[0])
LOG.info(f'Suite shutting down - {reason.args[0]}')
elif isinstance(reason, SchedulerError):
LOG.error('Suite shutting down - %s', reason)
LOG.error(f'Suite shutting down - {reason}')
elif isinstance(reason, SuiteConfigError):
LOG.error(f'{SuiteConfigError.__name__}: {reason}')
elif isinstance(reason, PlatformLookupError):
LOG.error(f'{PlatformLookupError.__name__}: {reason}')
else:
LOG.exception(reason)
LOG.critical('Suite shutting down - %s', reason)
if str(reason):
LOG.critical(f'Suite shutting down - {reason}')
else:
LOG.critical('Suite shutting down')

if self.proc_pool:
self.proc_pool.close()
Expand Down Expand Up @@ -1836,3 +1833,18 @@ def process_cylc_stop_point(self):
if stoppoint is not None:
self.options.stopcp = str(stoppoint)
self.pool.set_stop_point(get_point(self.options.stopcp))

async def handle_exception(self, exc):
"""Gracefully shut down the scheduler.
This re-raises the caught exception, to be caught higher up.
Args:
exc: The caught exception to be logged during the shutdown.
"""
try:
await self.shutdown(exc)
except Exception as exc2:
# In case of exceptions in the shutdown method itself
LOG.exception(exc2)
raise exc from None
8 changes: 1 addition & 7 deletions cylc/flow/scheduler_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,13 +406,7 @@ async def _run(parser, options, reg, is_restart, scheduler):
# stop cylc stop
except SchedulerError:
ret = 1
except KeyboardInterrupt as exc:
try:
await scheduler.shutdown(exc)
except Exception as exc2:
# In case of exceptions in the shutdown method itself.
LOG.exception(exc2)
raise exc2 from None
except (KeyboardInterrupt, asyncio.CancelledError):
ret = 2
except Exception:
ret = 3
Expand Down

0 comments on commit db993d5

Please sign in to comment.