From 4c00913b3bdd413a3e304a31fe9a332192d70013 Mon Sep 17 00:00:00 2001 From: goodboy Date: Thu, 7 May 2026 16:35:18 -0400 Subject: [PATCH] Add `terminate()` to `_ForkedProc` Sends `SIGTERM` (graceful shutdown) instead of the existing `kill()` which sends `SIGKILL`. Mirrors the `trio.Process.terminate()` / `multiprocessing.Process.terminate()` interface. Used by `ActorNursery.cancel()`'s per-child escalation when `Portal.cancel_actor()` raises `ActorTooSlowError`, and by the legacy `hard_kill=True` branch. Swallows `ProcessLookupError` (child already dead) same as `kill()`. (this patch was generated in some part by [`claude-code`][claude-code-gh]) [claude-code-gh]: https://github.com/anthropics/claude-code --- tractor/spawn/_main_thread_forkserver.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tractor/spawn/_main_thread_forkserver.py b/tractor/spawn/_main_thread_forkserver.py index 75c24197..f54d1ae7 100644 --- a/tractor/spawn/_main_thread_forkserver.py +++ b/tractor/spawn/_main_thread_forkserver.py @@ -760,6 +760,26 @@ class _ForkedProc: self._pidfd = -1 return self._returncode + def terminate(self) -> None: + ''' + OS-level `SIGTERM` to the child. Swallows + `ProcessLookupError` (already dead). + + Mirrors `trio.Process.terminate()` / + `multiprocessing.Process.terminate()` — sends SIGTERM + (graceful, allows the child a chance to clean up via + signal-handlers) rather than SIGKILL. Used by + `ActorNursery.cancel()`'s per-child escalation when + `Portal.cancel_actor()` raises `ActorTooSlowError`, + and by the legacy `hard_kill=True` branch on the same + path. + + ''' + try: + os.kill(self.pid, signal.SIGTERM) + except ProcessLookupError: + pass + def kill(self) -> None: ''' OS-level `SIGKILL` to the child. Swallows