structio/tests/self_cancel.py

47 lines
1.6 KiB
Python

import structio
async def sleeper(n):
print(f"[sleeper] Going to sleep for {n} seconds!")
i = structio.clock()
try:
await structio.sleep(n)
except structio.Cancelled:
print(f"[sleeper] Oh no, I've been cancelled! (was gonna sleep {structio.clock() - i:.2f} more seconds)")
raise
print("[sleeper] Woke up!")
async def main_simple(n, o, p):
print(f"[main] Parent is alive, spawning {o} children sleeping {n} seconds each")
t = structio.clock()
async with structio.create_pool() as pool:
for i in range(o):
pool.spawn(sleeper, n)
print(f"[main] Children spawned, sleeping {p} seconds before cancelling")
await structio.sleep(p)
# Note that cancellations propagate to all inner task scopes!
pool.scope.cancel()
print(f"[main] Parent exited in {structio.clock() - t:.2f} seconds")
async def main_nested(n, o, p):
print(f"[main] Parent is alive, spawning {o} children in two contexts sleeping {n} seconds each")
t = structio.clock()
async with structio.create_pool() as p1:
for i in range(o):
p1.spawn(sleeper, n)
async with structio.create_pool() as p2:
for i in range(o):
p2.spawn(sleeper, n)
print(f"[main] Children spawned, sleeping {p} seconds before cancelling")
await structio.sleep(p)
# Note that cancellations propagate to all inner task scopes!
p1.scope.cancel()
print(f"[main] Parent exited in {structio.clock() - t:.2f} seconds")
# Should take about 4 seconds
structio.run(main_simple, 5, 2, 2)
structio.run(main_nested, 5, 2, 2)