aquafire / test_terminate.py

Last active 6 months ago

Like 0

aquafire revised this gist 9 months ago · 1e91c73

1 file changed, 43 insertions

test_terminate.py (file created)
@@ -0,0 +1,43 @@
1 + import asyncio
2 + import signal
3 +
4 +
5 + async def shutdown(sig, loop):
6 + """Shutdown signal"""
7 + print(f"Received signal {sig.name}...")
8 + tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()]
9 + [task.cancel() for task in tasks]
10 +
11 + print(f"Cancelling {len(tasks)} outstanding tasks")
12 + await asyncio.gather(*tasks, return_exceptions=True)
13 + loop.stop()
14 +
15 +
16 + async def run_managed_subprocess():
17 + # 1. Start the process
18 + proc = await asyncio.create_subprocess_exec(
19 + "sleep", "300", stdout=asyncio.subprocess.PIPE
20 + )
21 + try:
22 + # 2. Wait for it (this is where cancellation will trigger)
23 + stdout, stderr = await proc.communicate()
24 + except asyncio.CancelledError:
25 + # 3. Handle cancellation: KILL THE PROCESS
26 + print("Task cancelled, terminating subprocess...")
27 + try:
28 + print("Поймали !")
29 + proc.terminate()
30 + # It is best practice to wait for it to actually exit
31 + await proc.wait()
32 + except ProcessLookupError:
33 + pass # Already gone
34 + raise # Re-raise to complete the cancellation
35 +
36 +
37 + # get current loop
38 + loop = asyncio.get_event_loop()
39 + # add handler
40 + loop.add_signal_handler(
41 + signal.SIGTERM, lambda: asyncio.create_task(shutdown(signal.SIGTERM, loop))
42 + )
43 + loop.run_until_complete(run_managed_subprocess())