You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

76 lines
2.7 KiB

2 years ago
  1. # Gracefully Stopping a Running Process
  2. >New in v1.0.9!
  3. <p align="center">
  4. <img src="https://github.com/chriskiehl/GooeyImages/raw/images/docs/graceful-stopping/screenshot.PNG"/>
  5. </p>
  6. **Contents:**
  7. * [How to tell Gooey which shutdown signal to use](#how-to-tell-gooey-which-signal-to-use)
  8. * [How to catch KeyboardInterrupts](#How-to-catch-KeyboardInterrupts)
  9. * [How to catch general interrupt signals](#How-to-catch-general-interrupt-signals)
  10. By default, Gooey will kill the child process without any chance for cleanup. This guide will explain how to adjust that behavior so that you can detect when Gooey is attempting to close your process and use that signal to shutdown gracefully.
  11. ### Basics: How to tell Gooey which shutdown signal to use:
  12. You can control the signal Gooey sends while stopping your process via `shutdown_signal` decorator argument. Signal values come from the builtin `signal` python module. On linux, any of the available constants may be used as a value. However, on Windows, only `CTRL_BREAK_EVENT`, `CTRL_C_EVENT` and `SIGTERM` are supported by the OS.
  13. ```python
  14. import signal
  15. @Gooey(shutdown_signal=signal.CTRL_C_EVENT)
  16. def main():
  17. ...
  18. ```
  19. ### How to catch KeyboardInterrupts:
  20. Keyboard interrupts are triggered in response to the `CTRL_C_EVENT` signal.
  21. ```python
  22. import signal
  23. @Gooey(shutdown_signal=signal.CTRL_C_EVENT)
  24. def main():
  25. ...
  26. ```
  27. Catching them in your code is really easy! They conveniently show up as top-level Exceptions. Just wrap your main logic in a try/except and you'll be able to catch when Gooey tries to shut down your process.
  28. ```python
  29. try
  30. # your code here
  31. except KeyboardInterrupt:
  32. # cleanup and shutdown or ignore
  33. ```
  34. ### How to catch general interrupt signals
  35. Handling other signals is only slightly more involved than the `CTRL_C_EVENT` one. You need to install a handler via the `signal` module and tie it to the specific signal you want to handle. Let's use the `CTRL_BREAK_EVENT` signal as example.
  36. ```python
  37. import signal
  38. # (1)
  39. def handler(*args):
  40. print("I am called in response to an external signal!")
  41. raise Exception("Kaboom!")
  42. # (2)
  43. signal.signal(signal.SIGBREAK, handler)
  44. # (3)
  45. @Gooey(shutdown_signal=signal.CTRL_BREAK_EVENT)
  46. def main():
  47. # your code here
  48. # ...
  49. ```
  50. Here we setup a handler called `handler` (1). This function can do anything you want in response to the signal including ignoring it entirely. Next we tie the signal we're interested in to the handler (2). Finally, we tell Gooey to send the `BREAK` signal(3) when the stop button is clicked.
  51. > Note: pay close attention to the different constants used while specifying a handler (e.g. `SIGBREAK`) versus specifying which signal will be sent (e.g. `CTRL_BREAK_SIGNAL`).