Skip to content

Commit

Permalink
handle windows
Browse files Browse the repository at this point in the history
  • Loading branch information
Carreau committed Feb 18, 2022
1 parent 8518d6f commit aaad575
Showing 1 changed file with 38 additions and 35 deletions.
73 changes: 38 additions & 35 deletions ipykernel/kernelbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -1136,8 +1136,7 @@ def _input_request(self, prompt, ident, parent, password=False):
raise EOFError
return value


async def _killpg(self, *, signal):
def _killpg(self, signal):
"""
similar to killpg but use psutil if it can on windows
or if pgid is none
Expand All @@ -1147,8 +1146,8 @@ async def _killpg(self, *, signal):
if pgid and hasattr(os, "killpg"):
try:
os.killpg(pgid, signal)
except OSError:
self.log.warning("OSError running killpg, not killing children")
except (OSError) as e:
self.log.exception(f"OSError running killpg, not killing children.")
return
elif psutil is not None:
children = parent.children(recursive=True)
Expand All @@ -1162,30 +1161,20 @@ async def _killpg(self, *, signal):
pass

async def _progressively_terminate_all_children(self):
if sys.platform == "win32":
self.log.info(f"Terminating subprocesses not yet supported on windows.")
return

pgid = os.getpgid(os.getpid())
if not pgid:
self.log.warning(f"No Pgid ({pgid}), not trying to stop subprocesses.")
return
if psutil is None:
# blindly send quickly sigterm/sigkill to processes if psutil not there.
self.log.debug("Please install psutil for a cleaner subprocess shutdown.")
self.log.info("Please install psutil for a cleaner subprocess shutdown.")
self._send_interupt_children()
try:
await asyncio.sleep(0.05)
self.log.debug("Sending SIGTERM to {pgid}")
self._killpg(SIGTERM)
await asyncio.sleep(0.05)
self.log.debug("Sending SIGKILL to {pgid}")
self._killpg(pgid, SIGKILL)
except Exception:
self.log.exception("Exception during subprocesses termination")
return

sleeps = (0.01, 0.03, 0.1, 0.3, 1)
await asyncio.sleep(0.05)
self.log.debug("Sending SIGTERM to {pgid}")
self._killpg(SIGTERM)
await asyncio.sleep(0.05)
self.log.debug("Sending SIGKILL to {pgid}")
self._killpg(pgid, SIGKILL)

sleeps = (0.01, 0.03, 0.1, 0.3, 1, 3, 10)
children = psutil.Process().children(recursive=True)
if not children:
self.log.debug("Kernel has no children.")
Expand All @@ -1195,24 +1184,38 @@ async def _progressively_terminate_all_children(self):

for signum in (SIGTERM, SIGKILL):
self.log.debug(
f"Will try to send {signum} ({Signals(signum)}) to subprocesses :{children}"
f"Will try to send {signum} ({Signals(signum)!r}) to subprocesses :{children}"
)
for delay in sleeps:
children = psutil.Process().children(recursive=True)
if not children:
self.log.debug("No more children, continuing shutdown routine.")
return
self._killpg(signum)
try:
if not children:
self.log.warning(
"No more children, continuing shutdown routine."
)
return
except psutil.NoSuchProcess:
pass
self._killpg(15)
self.log.debug(
f"Will sleep {delay}s before checking for children and retrying."
f"Will sleep {delay}s before checking for children and retrying. {children}"
)
await ascynio.sleep(delay)
await asyncio.sleep(delay)

async def _at_shutdown(self):
"""Actions taken at shutdown by the kernel, called by python's atexit.
"""
await self._progressively_terminate_all_children()
if self._shutdown_message is not None:
self.session.send(self.iopub_socket, self._shutdown_message, ident=self._topic('shutdown'))
self.log.debug("%s", self._shutdown_message)
self.control_stream.flush(zmq.POLLOUT)
try:
await self._progressively_terminate_all_children()
except Exception as e:
self.log.exception("Exception during subprocesses termination %s", e)

finally:
if self._shutdown_message is not None:
self.session.send(
self.iopub_socket,
self._shutdown_message,
ident=self._topic("shutdown"),
)
self.log.debug("%s", self._shutdown_message)
self.control_stream.flush(zmq.POLLOUT)

0 comments on commit aaad575

Please sign in to comment.