Compare commits
No commits in common. "8c90521562bce14c650aa30cd266aecd5df9f80a" and "4bc443ccae3aefcf1a33e7f047c19483e5f53a33" have entirely different histories.
8c90521562
...
4bc443ccae
|
@ -310,6 +310,7 @@ def test_subactor_breakpoint(
|
|||
|
||||
assert in_prompt_msg(
|
||||
child, [
|
||||
'MessagingError:',
|
||||
'RemoteActorError:',
|
||||
"('breakpoint_forever'",
|
||||
'bdb.BdbQuit',
|
||||
|
|
|
@ -410,6 +410,7 @@ def test_peer_canceller(
|
|||
'''
|
||||
async def main():
|
||||
async with tractor.open_nursery(
|
||||
# NOTE: to halt the peer tasks on ctxc, uncomment this.
|
||||
debug_mode=debug_mode,
|
||||
) as an:
|
||||
canceller: Portal = await an.start_actor(
|
||||
|
|
|
@ -101,9 +101,6 @@ from ._state import (
|
|||
debug_mode,
|
||||
_ctxvar_Context,
|
||||
)
|
||||
from .trionics import (
|
||||
collapse_eg,
|
||||
)
|
||||
# ------ - ------
|
||||
if TYPE_CHECKING:
|
||||
from ._portal import Portal
|
||||
|
@ -943,7 +940,7 @@ class Context:
|
|||
self.cancel_called = True
|
||||
|
||||
header: str = (
|
||||
f'Cancelling ctx from {side!r}-side\n'
|
||||
f'Cancelling ctx from {side.upper()}-side\n'
|
||||
)
|
||||
reminfo: str = (
|
||||
# ' =>\n'
|
||||
|
@ -951,7 +948,7 @@ class Context:
|
|||
f'\n'
|
||||
f'c)=> {self.chan.uid}\n'
|
||||
f' |_[{self.dst_maddr}\n'
|
||||
f' >> {self.repr_rpc}\n'
|
||||
f' >>{self.repr_rpc}\n'
|
||||
# f' >> {self._nsf}() -> {codec}[dict]:\n\n'
|
||||
# TODO: pull msg-type from spec re #320
|
||||
)
|
||||
|
@ -2026,8 +2023,10 @@ async def open_context_from_portal(
|
|||
ctxc_from_callee: ContextCancelled|None = None
|
||||
try:
|
||||
async with (
|
||||
collapse_eg(),
|
||||
trio.open_nursery() as tn,
|
||||
trio.open_nursery(
|
||||
strict_exception_groups=False,
|
||||
) as tn,
|
||||
|
||||
msgops.maybe_limit_plds(
|
||||
ctx=ctx,
|
||||
spec=ctx_meta.get('pld_spec'),
|
||||
|
|
|
@ -28,10 +28,7 @@ from typing import (
|
|||
from contextlib import asynccontextmanager as acm
|
||||
|
||||
from tractor.log import get_logger
|
||||
from .trionics import (
|
||||
gather_contexts,
|
||||
collapse_eg,
|
||||
)
|
||||
from .trionics import gather_contexts
|
||||
from .ipc import _connect_chan, Channel
|
||||
from ._addr import (
|
||||
UnwrappedAddress,
|
||||
|
@ -91,6 +88,7 @@ async def get_registry(
|
|||
yield regstr_ptl
|
||||
|
||||
|
||||
|
||||
@acm
|
||||
async def get_root(
|
||||
**kwargs,
|
||||
|
@ -251,12 +249,9 @@ async def find_actor(
|
|||
for addr in registry_addrs
|
||||
)
|
||||
portals: list[Portal]
|
||||
async with (
|
||||
collapse_eg(),
|
||||
gather_contexts(
|
||||
mngrs=maybe_portals,
|
||||
) as portals,
|
||||
):
|
||||
async with gather_contexts(
|
||||
mngrs=maybe_portals,
|
||||
) as portals:
|
||||
# log.runtime(
|
||||
# 'Gathered portals:\n'
|
||||
# f'{portals}'
|
||||
|
|
|
@ -39,10 +39,7 @@ import warnings
|
|||
|
||||
import trio
|
||||
|
||||
from .trionics import (
|
||||
maybe_open_nursery,
|
||||
collapse_eg,
|
||||
)
|
||||
from .trionics import maybe_open_nursery
|
||||
from ._state import (
|
||||
current_actor,
|
||||
)
|
||||
|
@ -561,13 +558,14 @@ async def open_portal(
|
|||
assert actor
|
||||
was_connected: bool = False
|
||||
|
||||
async with (
|
||||
collapse_eg(),
|
||||
maybe_open_nursery(
|
||||
tn,
|
||||
shield=shield,
|
||||
) as tn,
|
||||
):
|
||||
async with maybe_open_nursery(
|
||||
tn,
|
||||
shield=shield,
|
||||
strict_exception_groups=False,
|
||||
# ^XXX^ TODO? soo roll our own then ??
|
||||
# -> since we kinda want the "if only one `.exception` then
|
||||
# just raise that" interface?
|
||||
) as tn:
|
||||
|
||||
if not channel.connected():
|
||||
await channel.connect()
|
||||
|
|
|
@ -37,7 +37,13 @@ import warnings
|
|||
|
||||
import trio
|
||||
|
||||
from . import _runtime
|
||||
from ._runtime import (
|
||||
Actor,
|
||||
Arbiter,
|
||||
# TODO: rename and make a non-actor subtype?
|
||||
# Arbiter as Registry,
|
||||
async_main,
|
||||
)
|
||||
from .devx import (
|
||||
debug,
|
||||
_frame_stack,
|
||||
|
@ -58,7 +64,6 @@ from ._addr import (
|
|||
)
|
||||
from .trionics import (
|
||||
is_multi_cancelled,
|
||||
collapse_eg,
|
||||
)
|
||||
from ._exceptions import (
|
||||
RuntimeFailure,
|
||||
|
@ -192,13 +197,9 @@ async def open_root_actor(
|
|||
# read-only state to sublayers?
|
||||
# extra_rt_vars: dict|None = None,
|
||||
|
||||
) -> _runtime.Actor:
|
||||
) -> Actor:
|
||||
'''
|
||||
Initialize the `tractor` runtime by starting a "root actor" in
|
||||
a parent-most Python process.
|
||||
|
||||
All (disjoint) actor-process-trees-as-programs are created via
|
||||
this entrypoint.
|
||||
Runtime init entry point for ``tractor``.
|
||||
|
||||
'''
|
||||
# XXX NEVER allow nested actor-trees!
|
||||
|
@ -378,7 +379,7 @@ async def open_root_actor(
|
|||
f'Registry(s) seem(s) to exist @ {ponged_addrs}'
|
||||
)
|
||||
|
||||
actor = _runtime.Actor(
|
||||
actor = Actor(
|
||||
name=name or 'anonymous',
|
||||
uuid=mk_uuid(),
|
||||
registry_addrs=ponged_addrs,
|
||||
|
@ -413,8 +414,7 @@ async def open_root_actor(
|
|||
# https://github.com/goodboy/tractor/pull/348
|
||||
# https://github.com/goodboy/tractor/issues/296
|
||||
|
||||
# TODO: rename as `RootActor` or is that even necessary?
|
||||
actor = _runtime.Arbiter(
|
||||
actor = Arbiter(
|
||||
name=name or 'registrar',
|
||||
uuid=mk_uuid(),
|
||||
registry_addrs=registry_addrs,
|
||||
|
@ -441,13 +441,13 @@ async def open_root_actor(
|
|||
f'{ml_addrs_str}'
|
||||
)
|
||||
|
||||
# start runtime in a bg sub-task, yield to caller.
|
||||
async with (
|
||||
collapse_eg(),
|
||||
trio.open_nursery() as root_tn,
|
||||
):
|
||||
# start the actor runtime in a new task
|
||||
async with trio.open_nursery(
|
||||
strict_exception_groups=False,
|
||||
# ^XXX^ TODO? instead unpack any RAE as per "loose" style?
|
||||
) as nursery:
|
||||
|
||||
# `_runtime.async_main()` creates an internal nursery
|
||||
# ``_runtime.async_main()`` creates an internal nursery
|
||||
# and blocks here until any underlying actor(-process)
|
||||
# tree has terminated thereby conducting so called
|
||||
# "end-to-end" structured concurrency throughout an
|
||||
|
@ -455,9 +455,9 @@ async def open_root_actor(
|
|||
# "actor runtime" primitives are SC-compat and thus all
|
||||
# transitively spawned actors/processes must be as
|
||||
# well.
|
||||
await root_tn.start(
|
||||
await nursery.start(
|
||||
partial(
|
||||
_runtime.async_main,
|
||||
async_main,
|
||||
actor,
|
||||
accept_addrs=trans_bind_addrs,
|
||||
parent_addr=None
|
||||
|
|
|
@ -756,6 +756,7 @@ async def _invoke(
|
|||
BaseExceptionGroup,
|
||||
BaseException,
|
||||
trio.Cancelled,
|
||||
|
||||
) as _scope_err:
|
||||
scope_err = _scope_err
|
||||
if (
|
||||
|
|
|
@ -74,9 +74,6 @@ from tractor.msg import (
|
|||
pretty_struct,
|
||||
types as msgtypes,
|
||||
)
|
||||
from .trionics import (
|
||||
collapse_eg,
|
||||
)
|
||||
from .ipc import (
|
||||
Channel,
|
||||
# IPCServer, # causes cycles atm..
|
||||
|
@ -348,7 +345,7 @@ class Actor:
|
|||
|
||||
def pformat(
|
||||
self,
|
||||
ds: str = ': ',
|
||||
ds: str = ':',
|
||||
indent: int = 0,
|
||||
) -> str:
|
||||
fields_sect_prefix: str = ' |_'
|
||||
|
@ -1057,7 +1054,6 @@ class Actor:
|
|||
cid: str,
|
||||
parent_chan: Channel,
|
||||
requesting_uid: tuple[str, str]|None,
|
||||
# ^^TODO! use the `Aid` directly here!
|
||||
|
||||
ipc_msg: dict|None|bool = False,
|
||||
|
||||
|
@ -1103,12 +1099,9 @@ class Actor:
|
|||
|
||||
log.cancel(
|
||||
'Rxed cancel request for RPC task\n'
|
||||
f'{ctx._task!r} <=c) {requesting_uid}\n'
|
||||
f'|_>> {ctx.repr_rpc}\n'
|
||||
|
||||
# f'|_{ctx._task}\n'
|
||||
# f' >> {ctx.repr_rpc}\n'
|
||||
|
||||
f'<=c) {requesting_uid}\n'
|
||||
f' |_{ctx._task}\n'
|
||||
f' >> {ctx.repr_rpc}\n'
|
||||
# f'=> {ctx._task}\n'
|
||||
# f' >> Actor._cancel_task() => {ctx._task}\n'
|
||||
# f' |_ {ctx._task}\n\n'
|
||||
|
@ -1393,12 +1386,10 @@ async def async_main(
|
|||
# parent is kept alive as a resilient service until
|
||||
# cancellation steps have (mostly) occurred in
|
||||
# a deterministic way.
|
||||
root_tn: trio.Nursery
|
||||
async with (
|
||||
collapse_eg(),
|
||||
trio.open_nursery() as root_tn,
|
||||
):
|
||||
actor._root_n = root_tn
|
||||
async with trio.open_nursery(
|
||||
strict_exception_groups=False,
|
||||
) as root_nursery:
|
||||
actor._root_n = root_nursery
|
||||
assert actor._root_n
|
||||
|
||||
ipc_server: _server.IPCServer
|
||||
|
@ -1497,7 +1488,7 @@ async def async_main(
|
|||
# their root actor over that channel.
|
||||
if _state._runtime_vars['_is_root']:
|
||||
for addr in accept_addrs:
|
||||
waddr: Address = wrap_address(addr)
|
||||
waddr = wrap_address(addr)
|
||||
if waddr == waddr.get_root():
|
||||
_state._runtime_vars['_root_mailbox'] = addr
|
||||
|
||||
|
@ -1542,7 +1533,7 @@ async def async_main(
|
|||
# start processing parent requests until our channel
|
||||
# server is 100% up and running.
|
||||
if actor._parent_chan:
|
||||
await root_tn.start(
|
||||
await root_nursery.start(
|
||||
partial(
|
||||
_rpc.process_messages,
|
||||
chan=actor._parent_chan,
|
||||
|
|
|
@ -42,7 +42,6 @@ from ._runtime import Actor
|
|||
from ._portal import Portal
|
||||
from .trionics import (
|
||||
is_multi_cancelled,
|
||||
collapse_eg,
|
||||
)
|
||||
from ._exceptions import (
|
||||
ContextCancelled,
|
||||
|
@ -325,10 +324,9 @@ class ActorNursery:
|
|||
server: IPCServer = self._actor.ipc_server
|
||||
|
||||
with trio.move_on_after(3) as cs:
|
||||
async with (
|
||||
collapse_eg(),
|
||||
trio.open_nursery() as tn,
|
||||
):
|
||||
async with trio.open_nursery(
|
||||
strict_exception_groups=False,
|
||||
) as tn:
|
||||
|
||||
subactor: Actor
|
||||
proc: trio.Process
|
||||
|
@ -421,10 +419,10 @@ async def _open_and_supervise_one_cancels_all_nursery(
|
|||
# `ActorNursery.start_actor()`).
|
||||
|
||||
# errors from this daemon actor nursery bubble up to caller
|
||||
async with (
|
||||
collapse_eg(),
|
||||
trio.open_nursery() as da_nursery,
|
||||
):
|
||||
async with trio.open_nursery(
|
||||
strict_exception_groups=False,
|
||||
# ^XXX^ TODO? instead unpack any RAE as per "loose" style?
|
||||
) as da_nursery:
|
||||
try:
|
||||
# This is the inner level "run in actor" nursery. It is
|
||||
# awaited first since actors spawned in this way (using
|
||||
|
@ -434,10 +432,11 @@ async def _open_and_supervise_one_cancels_all_nursery(
|
|||
# immediately raised for handling by a supervisor strategy.
|
||||
# As such if the strategy propagates any error(s) upwards
|
||||
# the above "daemon actor" nursery will be notified.
|
||||
async with (
|
||||
collapse_eg(),
|
||||
trio.open_nursery() as ria_nursery,
|
||||
):
|
||||
async with trio.open_nursery(
|
||||
strict_exception_groups=False,
|
||||
# ^XXX^ TODO? instead unpack any RAE as per "loose" style?
|
||||
) as ria_nursery:
|
||||
|
||||
an = ActorNursery(
|
||||
actor,
|
||||
ria_nursery,
|
||||
|
|
|
@ -238,8 +238,7 @@ def enable_stack_on_sig(
|
|||
import stackscope
|
||||
except ImportError:
|
||||
log.error(
|
||||
'`stackscope` not installed for use in debug mode!\n'
|
||||
'`Ignoring {enable_stack_on_sig!r} call!\n'
|
||||
'`stackscope` not installed for use in debug mode!'
|
||||
)
|
||||
return None
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ async def maybe_wait_on_canced_subs(
|
|||
log.cancel(
|
||||
'Waiting on cancel request to peer..\n'
|
||||
f'c)=>\n'
|
||||
f' |_{chan.aid}\n'
|
||||
f' |_{chan.uid}\n'
|
||||
)
|
||||
|
||||
# XXX: this is a soft wait on the channel (and its
|
||||
|
@ -156,7 +156,7 @@ async def maybe_wait_on_canced_subs(
|
|||
# local runtime here is now cancelled while
|
||||
# (presumably) in the middle of msg loop processing.
|
||||
chan_info: str = (
|
||||
f'{chan.aid}\n'
|
||||
f'{chan.uid}\n'
|
||||
f'|_{chan}\n'
|
||||
f' |_{chan.transport}\n\n'
|
||||
)
|
||||
|
@ -279,7 +279,7 @@ async def maybe_wait_on_canced_subs(
|
|||
log.runtime(
|
||||
f'Peer IPC broke but subproc is alive?\n\n'
|
||||
|
||||
f'<=x {chan.aid}@{chan.raddr}\n'
|
||||
f'<=x {chan.uid}@{chan.raddr}\n'
|
||||
f' |_{proc}\n'
|
||||
)
|
||||
|
||||
|
@ -460,7 +460,7 @@ async def handle_stream_from_peer(
|
|||
# drop ref to channel so it can be gc-ed and disconnected
|
||||
con_teardown_status: str = (
|
||||
f'IPC channel disconnected:\n'
|
||||
f'<=x uid: {chan.aid}\n'
|
||||
f'<=x uid: {chan.uid}\n'
|
||||
f' |_{pformat(chan)}\n\n'
|
||||
)
|
||||
chans.remove(chan)
|
||||
|
@ -468,7 +468,7 @@ async def handle_stream_from_peer(
|
|||
# TODO: do we need to be this pedantic?
|
||||
if not chans:
|
||||
con_teardown_status += (
|
||||
f'-> No more channels with {chan.aid}'
|
||||
f'-> No more channels with {chan.uid}'
|
||||
)
|
||||
server._peers.pop(uid, None)
|
||||
|
||||
|
@ -519,7 +519,7 @@ async def handle_stream_from_peer(
|
|||
and
|
||||
(ctx_in_debug := pdb_lock.ctx_in_debug)
|
||||
and
|
||||
(pdb_user_uid := ctx_in_debug.chan.aid)
|
||||
(pdb_user_uid := ctx_in_debug.chan.uid)
|
||||
):
|
||||
entry: tuple|None = local_nursery._children.get(
|
||||
tuple(pdb_user_uid)
|
||||
|
|
|
@ -40,7 +40,7 @@ from typing import (
|
|||
import trio
|
||||
from tractor._state import current_actor
|
||||
from tractor.log import get_logger
|
||||
from ._beg import collapse_eg
|
||||
# from ._beg import collapse_eg
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
@ -151,8 +151,13 @@ async def gather_contexts(
|
|||
)
|
||||
|
||||
async with (
|
||||
collapse_eg(),
|
||||
trio.open_nursery() as tn,
|
||||
# collapse_eg(),
|
||||
trio.open_nursery(
|
||||
# strict_exception_groups=False,
|
||||
# ^XXX^ TODO? soo roll our own then ??
|
||||
# -> since we kinda want the "if only one `.exception` then
|
||||
# just raise that" interface?
|
||||
) as tn,
|
||||
):
|
||||
for mngr in mngrs:
|
||||
tn.start_soon(
|
||||
|
|
Loading…
Reference in New Issue