Open
Description
The problem: when a task starts a shielded subtask, but is cancelled before the subtask re-parents itself, the cancellation isn't propagated until the subtask ends.
Consider this code:
import trio
async def t(task_status):
with trio.CancelScope(shield=True) as sc: # turn off shielding, the code works
await trio.sleep(2)
print("Send",sc)
task_status.started(sc)
await trio.sleep(3)
print("Terminating")
async def r(tg):
sc = await tg.start(t)
print("Receive",sc)
sc.cancel()
async def main():
async with trio.open_nursery() as tg:
tg.start_soon(r,tg)
await trio.sleep(1)
tg.cancel_scope.cancel() # comment this off, the code works
trio.run(main)
What I expect to happen is that tg.start
returns the value from task_status.started
, task t
gets cancelled, this code takes one second to run.
In my "real" usecase the subtask starts a database connection which must be (a) cached and (b) closed properly. Thus turning off the shield won't work. The cancellation in the last line of main
is a stand-in for any kund of exception that might happen in the rest of the program.
Metadata
Metadata
Assignees
Labels
No labels