forked from goodboy/tractor
Implicitly open root actor on first nursery use.
parent
bd3059f01b
commit
0bb2163b0c
|
@ -5,15 +5,17 @@ from functools import partial
|
||||||
import multiprocessing as mp
|
import multiprocessing as mp
|
||||||
from typing import Tuple, List, Dict, Optional, Any
|
from typing import Tuple, List, Dict, Optional, Any
|
||||||
import typing
|
import typing
|
||||||
|
from contextlib import AsyncExitStack
|
||||||
|
|
||||||
import trio
|
import trio
|
||||||
from async_generator import asynccontextmanager
|
from async_generator import asynccontextmanager
|
||||||
|
|
||||||
from ._state import current_actor
|
from ._state import current_actor, is_root_process, is_main_process
|
||||||
from .log import get_logger, get_loglevel
|
from .log import get_logger, get_loglevel
|
||||||
from ._actor import Actor
|
from ._actor import Actor
|
||||||
from ._portal import Portal
|
from ._portal import Portal
|
||||||
from ._exceptions import is_multi_cancelled
|
from ._exceptions import is_multi_cancelled
|
||||||
|
from ._root import open_root_actor
|
||||||
from . import _state
|
from . import _state
|
||||||
from . import _spawn
|
from . import _spawn
|
||||||
|
|
||||||
|
@ -186,7 +188,9 @@ class ActorNursery:
|
||||||
|
|
||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
async def open_nursery() -> typing.AsyncGenerator[ActorNursery, None]:
|
async def open_nursery(
|
||||||
|
**kwargs,
|
||||||
|
) -> typing.AsyncGenerator[ActorNursery, None]:
|
||||||
"""Create and yield a new ``ActorNursery`` to be used for spawning
|
"""Create and yield a new ``ActorNursery`` to be used for spawning
|
||||||
structured concurrent subactors.
|
structured concurrent subactors.
|
||||||
|
|
||||||
|
@ -200,9 +204,23 @@ async def open_nursery() -> typing.AsyncGenerator[ActorNursery, None]:
|
||||||
anyway since it is more clear from the following nested nurseries
|
anyway since it is more clear from the following nested nurseries
|
||||||
which cancellation scopes correspond to each spawned subactor set.
|
which cancellation scopes correspond to each spawned subactor set.
|
||||||
"""
|
"""
|
||||||
actor = current_actor()
|
implicit_runtime = False
|
||||||
if not actor:
|
|
||||||
raise RuntimeError("No actor instance has been defined yet?")
|
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] = {}
|
||||||
|
@ -213,6 +231,7 @@ async def open_nursery() -> typing.AsyncGenerator[ActorNursery, None]:
|
||||||
# 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:
|
||||||
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
|
||||||
|
@ -307,6 +326,13 @@ async def open_nursery() -> typing.AsyncGenerator[ActorNursery, None]:
|
||||||
else:
|
else:
|
||||||
raise list(errors.values())[0]
|
raise list(errors.values())[0]
|
||||||
|
|
||||||
# ria_nursery scope end
|
# ria_nursery scope end - nursery checkpoint
|
||||||
|
|
||||||
|
# after nursery exit
|
||||||
|
finally:
|
||||||
log.debug("Nursery teardown complete")
|
log.debug("Nursery teardown complete")
|
||||||
|
|
||||||
|
# shutdown runtime if it was started
|
||||||
|
if implicit_runtime:
|
||||||
|
log.info("Shutting down actor tree")
|
||||||
|
await root_runtime_stack.aclose()
|
||||||
|
|
Loading…
Reference in New Issue