Handle abort in exclusive output state correctly

If the event loop is stopped while something holds the exclusive output, the
"log" singleton is now reset so the main thread can print a few more messages
before exiting.
This commit is contained in:
Joscha 2021-05-22 18:58:00 +02:00
parent 552cd82802
commit afac22c562
2 changed files with 18 additions and 1 deletions

View File

@ -115,11 +115,11 @@ def main() -> None:
dump_config(args, config)
exit()
# TODO Unset exclusive output on exceptions (if it was being held)
pferd = Pferd(config)
try:
asyncio.run(pferd.run())
except KeyboardInterrupt:
log.unlock()
log.explain_topic("Interrupted, exiting immediately")
log.explain("Open files and connections are left for the OS to clean up")
log.explain("Temporary files are not cleaned up")
@ -128,5 +128,6 @@ def main() -> None:
# reconsider what exit code to use here.
exit(1)
except Exception:
log.unlock()
log.unexpected_exception()
exit(1)

View File

@ -97,12 +97,28 @@ class Log:
self.print(line)
self._lines = []
def unlock(self) -> None:
"""
Get rid of an exclusive output state.
This function is meant to let PFERD print log messages after the event
loop was forcibly stopped and if it will not be started up again. After
this is called, it is not safe to use any functions except the logging
functions (print, warn, ...).
"""
self._progress_suspended = False
for line in self._lines:
self.print(line)
def print(self, text: str) -> None:
if self._progress_suspended:
self._lines.append(text)
else:
self.console.print(text)
# TODO Print errors (and warnings?) to stderr
def warn(self, text: str) -> None:
self.print(f"[bold bright_red]Warning[/] {escape(text)}")