forked from goodboy/tractor
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.cancelled: bool = False
|
||||||
self._join_procs = trio.Event()
|
self._join_procs = trio.Event()
|
||||||
self.errors = errors
|
self.errors = errors
|
||||||
|
self.exited = trio.Event()
|
||||||
|
|
||||||
async def start_actor(
|
async def start_actor(
|
||||||
self,
|
self,
|
||||||
|
@ -207,7 +208,8 @@ class ActorNursery:
|
||||||
|
|
||||||
# spawn cancel tasks for each sub-actor
|
# spawn cancel tasks for each sub-actor
|
||||||
assert portal
|
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)
|
# if we cancelled the cancel (we hung cancelling remote actors)
|
||||||
# then hard kill all sub-processes
|
# then hard kill all sub-processes
|
||||||
|
@ -401,18 +403,23 @@ async def open_nursery(
|
||||||
async with open_root_actor(**kwargs) as actor:
|
async with open_root_actor(**kwargs) as actor:
|
||||||
assert actor is current_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(
|
async with _open_and_supervise_one_cancels_all_nursery(
|
||||||
actor
|
actor
|
||||||
) as anursery:
|
) as anursery:
|
||||||
yield anursery
|
yield anursery
|
||||||
|
finally:
|
||||||
else: # sub-nursery case
|
anursery.exited.set()
|
||||||
|
|
||||||
async with _open_and_supervise_one_cancels_all_nursery(
|
|
||||||
actor
|
|
||||||
) as anursery:
|
|
||||||
yield anursery
|
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
log.debug("Nursery teardown complete")
|
log.debug("Nursery teardown complete")
|
||||||
|
|
Loading…
Reference in New Issue