|
1 | 1 | import os
|
2 | 2 | import sys
|
| 3 | +import time |
3 | 4 | import signal
|
4 |
| -import psutil |
5 | 5 | import shutil
|
6 | 6 | import asyncio
|
7 | 7 | import tempfile
|
| 8 | +import subprocess |
8 | 9 | from typing import List, Dict, Optional, Callable
|
9 | 10 |
|
10 | 11 |
|
11 | 12 | def kill_process_and_descendants(pid, termination_timeout):
|
12 |
| - def on_terminate(proc): |
13 |
| - print("process %s terminated" % proc) |
| 13 | + try: |
| 14 | + subprocess.check_call(["pkill", "-TERM", "-P", str(pid)]) |
| 15 | + except subprocess.CalledProcessError as e: |
| 16 | + pass |
| 17 | + |
| 18 | + time.sleep(termination_timeout) |
14 | 19 |
|
15 | 20 | try:
|
16 |
| - parent = psutil.Process(pid) |
17 |
| - children = parent.children(recursive=True) |
18 |
| - for p in children: |
19 |
| - p.terminate() |
20 |
| - _, alive = psutil.wait_procs( |
21 |
| - children, timeout=termination_timeout, callback=on_terminate |
22 |
| - ) |
23 |
| - for p in alive: |
24 |
| - p.kill() |
25 |
| - except psutil.NoSuchProcess: |
| 21 | + subprocess.check_call(["pkill", "-KILL", "-P", str(pid)]) |
| 22 | + except subprocess.CalledProcessError as e: |
26 | 23 | pass
|
27 | 24 |
|
28 | 25 |
|
@@ -226,16 +223,11 @@ def cleanup(self):
|
226 | 223 | if self.run_called:
|
227 | 224 | shutil.rmtree(self.temp_dir, ignore_errors=True)
|
228 | 225 |
|
229 |
| - async def kill(self, termination_timeout: float = 5): |
| 226 | + async def kill(self, termination_timeout: float = 1): |
230 | 227 | """Kill the subprocess and its descendants."""
|
231 | 228 |
|
232 | 229 | if self.process is not None:
|
233 | 230 | kill_process_and_descendants(self.process.pid, termination_timeout)
|
234 |
| - self.process.terminate() |
235 |
| - try: |
236 |
| - await asyncio.wait_for(self.process.wait(), termination_timeout) |
237 |
| - except asyncio.TimeoutError: |
238 |
| - self.process.kill() |
239 | 231 | else:
|
240 | 232 | print("No process to kill.")
|
241 | 233 |
|
|
0 commit comments