forked from goodboy/tractor
Factor OCA supervisor into new func
parent
35775c6763
commit
b285db4c58
|
@ -164,7 +164,10 @@ async def open_root_actor(
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
yield actor
|
yield actor
|
||||||
# result = await main()
|
|
||||||
|
# except BaseException as err:
|
||||||
|
# breakpoint()
|
||||||
|
|
||||||
except (Exception, trio.MultiError) as err:
|
except (Exception, trio.MultiError) as err:
|
||||||
logger.exception("Actor crashed:")
|
logger.exception("Actor crashed:")
|
||||||
await _debug._maybe_enter_pm(err)
|
await _debug._maybe_enter_pm(err)
|
||||||
|
|
|
@ -201,38 +201,9 @@ class ActorNursery:
|
||||||
|
|
||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
async def open_nursery(
|
async def _open_and_supervise_one_cancels_all_nursery(
|
||||||
**kwargs,
|
actor: Actor,
|
||||||
) -> typing.AsyncGenerator[ActorNursery, None]:
|
) -> typing.AsyncGenerator[ActorNursery, None]:
|
||||||
"""Create and yield a new ``ActorNursery`` to be used for spawning
|
|
||||||
structured concurrent subactors.
|
|
||||||
|
|
||||||
When an actor is spawned a new trio task is started which
|
|
||||||
invokes one of the process spawning backends to create and start
|
|
||||||
a new subprocess. These tasks are started by one of two nurseries
|
|
||||||
detailed below. The reason for spawning processes from within
|
|
||||||
a new task is because ``trio_run_in_process`` itself creates a new
|
|
||||||
internal nursery and the same task that opens a nursery **must**
|
|
||||||
close it. It turns out this approach is probably more correct
|
|
||||||
anyway since it is more clear from the following nested nurseries
|
|
||||||
which cancellation scopes correspond to each spawned subactor set.
|
|
||||||
"""
|
|
||||||
implicit_runtime = False
|
|
||||||
|
|
||||||
actor = current_actor(err_on_no_runtime=False)
|
|
||||||
|
|
||||||
if actor is None and is_main_process():
|
|
||||||
|
|
||||||
# if we are the parent process start the actor runtime implicitly
|
|
||||||
log.info("Starting actor runtime!")
|
|
||||||
root_runtime_stack = AsyncExitStack()
|
|
||||||
actor = await root_runtime_stack.enter_async_context(
|
|
||||||
open_root_actor(**kwargs)
|
|
||||||
)
|
|
||||||
assert actor is current_actor()
|
|
||||||
|
|
||||||
# mark us for teardown on exit
|
|
||||||
implicit_runtime = True
|
|
||||||
|
|
||||||
# the collection of errors retreived from spawned sub-actors
|
# the collection of errors retreived from spawned sub-actors
|
||||||
errors: Dict[Tuple[str, str], Exception] = {}
|
errors: Dict[Tuple[str, str], Exception] = {}
|
||||||
|
@ -243,7 +214,8 @@ async def open_nursery(
|
||||||
# a supervisor strategy **before** blocking indefinitely to wait for
|
# a supervisor strategy **before** blocking indefinitely to wait for
|
||||||
# actors spawned in "daemon mode" (aka started using
|
# actors spawned in "daemon mode" (aka started using
|
||||||
# ``ActorNursery.start_actor()``).
|
# ``ActorNursery.start_actor()``).
|
||||||
try:
|
|
||||||
|
# errors from this daemon actor nursery bubble up to caller
|
||||||
async with trio.open_nursery() as da_nursery:
|
async with trio.open_nursery() as da_nursery:
|
||||||
try:
|
try:
|
||||||
# This is the inner level "run in actor" nursery. It is
|
# This is the inner level "run in actor" nursery. It is
|
||||||
|
@ -348,6 +320,49 @@ async def open_nursery(
|
||||||
# ria_nursery scope end - nursery checkpoint
|
# ria_nursery scope end - nursery checkpoint
|
||||||
|
|
||||||
# after nursery exit
|
# after nursery exit
|
||||||
|
|
||||||
|
|
||||||
|
@asynccontextmanager
|
||||||
|
async def open_nursery(
|
||||||
|
**kwargs,
|
||||||
|
) -> typing.AsyncGenerator[ActorNursery, None]:
|
||||||
|
"""Create and yield a new ``ActorNursery`` to be used for spawning
|
||||||
|
structured concurrent subactors.
|
||||||
|
|
||||||
|
When an actor is spawned a new trio task is started which
|
||||||
|
invokes one of the process spawning backends to create and start
|
||||||
|
a new subprocess. These tasks are started by one of two nurseries
|
||||||
|
detailed below. The reason for spawning processes from within
|
||||||
|
a new task is because ``trio_run_in_process`` itself creates a new
|
||||||
|
internal nursery and the same task that opens a nursery **must**
|
||||||
|
close it. It turns out this approach is probably more correct
|
||||||
|
anyway since it is more clear from the following nested nurseries
|
||||||
|
which cancellation scopes correspond to each spawned subactor set.
|
||||||
|
"""
|
||||||
|
implicit_runtime = False
|
||||||
|
|
||||||
|
actor = current_actor(err_on_no_runtime=False)
|
||||||
|
|
||||||
|
if actor is None and is_main_process():
|
||||||
|
|
||||||
|
# if we are the parent process start the actor runtime implicitly
|
||||||
|
log.info("Starting actor runtime!")
|
||||||
|
root_runtime_stack = AsyncExitStack()
|
||||||
|
actor = await root_runtime_stack.enter_async_context(
|
||||||
|
open_root_actor(**kwargs)
|
||||||
|
)
|
||||||
|
assert actor is current_actor()
|
||||||
|
|
||||||
|
# mark us for teardown on exit
|
||||||
|
implicit_runtime = True
|
||||||
|
|
||||||
|
try:
|
||||||
|
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