aquafire / test_terminate.py

Last active 6 months ago

Like 0

Revision 1e91c732487992a491294b155be3b7ec68d1ac9f

test_terminate.py Raw
1import asyncio
2import signal
3
4
5async 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
16async 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
38loop = asyncio.get_event_loop()
39# add handler
40loop.add_signal_handler(
41 signal.SIGTERM, lambda: asyncio.create_task(shutdown(signal.SIGTERM, loop))
42)
43loop.run_until_complete(run_managed_subprocess())
44