Add a nursery "exited" signal
Use a `trio.Event` to enable nursery closure detection such that core runtime tasks can be notified when a local nursery exits and allow shutdown protocols to operate without close-before-terminate issues (such as IPC channel closure during remote peer cancellation).acked_backup
parent
a23afb0bb8
commit
d817f1a658
|
@ -52,6 +52,7 @@ class ActorNursery:
|
|||
self.cancelled: bool = False
|
||||
self._join_procs = trio.Event()
|
||||
self.errors = errors
|
||||
self.exited = trio.Event()
|
||||
|
||||
async def start_actor(
|
||||
self,
|
||||
|
@ -207,7 +208,8 @@ class ActorNursery:
|
|||
|
||||
# spawn cancel tasks for each sub-actor
|
||||
assert portal
|
||||
nursery.start_soon(portal.cancel_actor)
|
||||
if portal.channel.connected():
|
||||
nursery.start_soon(portal.cancel_actor)
|
||||
|
||||
# if we cancelled the cancel (we hung cancelling remote actors)
|
||||
# then hard kill all sub-processes
|
||||
|
@ -401,18 +403,23 @@ async def open_nursery(
|
|||
async with open_root_actor(**kwargs) as actor:
|
||||
assert actor is current_actor()
|
||||
|
||||
# try:
|
||||
try:
|
||||
async with _open_and_supervise_one_cancels_all_nursery(
|
||||
actor
|
||||
) as anursery:
|
||||
yield anursery
|
||||
finally:
|
||||
anursery.exited.set()
|
||||
|
||||
else: # sub-nursery case
|
||||
|
||||
try:
|
||||
async with _open_and_supervise_one_cancels_all_nursery(
|
||||
actor
|
||||
) as anursery:
|
||||
yield anursery
|
||||
|
||||
else: # sub-nursery case
|
||||
|
||||
async with _open_and_supervise_one_cancels_all_nursery(
|
||||
actor
|
||||
) as anursery:
|
||||
yield anursery
|
||||
finally:
|
||||
anursery.exited.set()
|
||||
|
||||
finally:
|
||||
log.debug("Nursery teardown complete")
|
||||
|
|
Loading…
Reference in New Issue