Skip to content

Commit

Permalink
Catch SIGTERM and kill running process before exitting (#244)
Browse files Browse the repository at this point in the history
* catch sigterm properly

* remove log
  • Loading branch information
samuelcolvin authored Aug 24, 2023
1 parent ea31274 commit eb0df3a
Showing 1 changed file with 18 additions and 0 deletions.
18 changes: 18 additions & 0 deletions watchfiles/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ def foobar(a, b, c):
target_type = detect_target_type(target)

logger.debug('running "%s" as %s', target, target_type)
catch_sigterm()
process = start_process(target, target_type, args, kwargs)
reloads = 0

Expand Down Expand Up @@ -207,6 +208,7 @@ async def main():
target_type = detect_target_type(target)

logger.debug('running "%s" as %s', target, target_type)
catch_sigterm()
process = await anyio.to_thread.run_sync(start_process, target, target_type, args, kwargs)
reloads = 0

Expand Down Expand Up @@ -421,3 +423,19 @@ def set_tty(tty_path: Optional[str]) -> Generator[None, None, None]:
else:
# currently on windows tty_path is None and there's nothing we can do here
yield


def raise_keyboard_interrupt(signum: int, _frame: Any) -> None: # pragma: no cover
logger.warning('received signal %s, raising KeyboardInterrupt', signal.Signals(signum))
raise KeyboardInterrupt


def catch_sigterm() -> None:
"""
Catch SIGTERM and raise KeyboardInterrupt instead. This means watchfiles will stop quickly
on `docker compose stop` and other cases where SIGTERM is sent.
Without this the watchfiles process will be killed while a running process will continue uninterrupted.
"""
logger.debug('registering handler for SIGTERM on watchfiles process %d', os.getpid())
signal.signal(signal.SIGTERM, raise_keyboard_interrupt)

0 comments on commit eb0df3a

Please sign in to comment.