Compare commits
No commits in common. "efcac594c1012470f477785593e7bbfb7bccd334" and "e617b498ecc98e713551f5bf9d73fec7d981b3db" have entirely different histories.
efcac594c1
...
e617b498ec
|
|
@ -152,27 +152,23 @@ async def test_trynamic_trio(
|
||||||
for the directed subs.
|
for the directed subs.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
async with (
|
async with tractor.open_nursery() as n:
|
||||||
tractor.open_nursery() as n,
|
|
||||||
trio.open_nursery() as tn,
|
|
||||||
):
|
|
||||||
print("Alright... Action!")
|
print("Alright... Action!")
|
||||||
|
|
||||||
# donny + gretchen each wait on the *other* to register, so
|
donny = await n.run_in_actor(
|
||||||
# they must run CONCURRENTLY — schedule both one-shots into a
|
|
||||||
# local task-nursery (was two non-blocking `run_in_actor()`s).
|
|
||||||
async def _direct(this_name: str, other_actor: str):
|
|
||||||
res = await tractor.to_actor.run(
|
|
||||||
ria_fn,
|
ria_fn,
|
||||||
an=n,
|
other_actor='gretchen',
|
||||||
other_actor=other_actor,
|
|
||||||
reg_addr=reg_addr,
|
reg_addr=reg_addr,
|
||||||
name=this_name,
|
name='donny',
|
||||||
)
|
)
|
||||||
print(res)
|
gretchen = await n.run_in_actor(
|
||||||
|
ria_fn,
|
||||||
tn.start_soon(_direct, 'donny', 'gretchen')
|
other_actor='donny',
|
||||||
tn.start_soon(_direct, 'gretchen', 'donny')
|
reg_addr=reg_addr,
|
||||||
|
name='gretchen',
|
||||||
|
)
|
||||||
|
print(await gretchen.result())
|
||||||
|
print(await donny.result())
|
||||||
print("CUTTTT CUUTT CUT!!?! Donny!! You're supposed to say...")
|
print("CUTTTT CUUTT CUT!!?! Donny!! You're supposed to say...")
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -274,15 +270,13 @@ async def spawn_and_check_registry(
|
||||||
portals = {}
|
portals = {}
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
name = f'a{i}'
|
name = f'a{i}'
|
||||||
# a daemon subactor is alive + registered
|
if with_streaming:
|
||||||
# without a "main" task; the streaming
|
|
||||||
# branch below uses the module funcs, the
|
|
||||||
# non-streaming case just needs it up (was
|
|
||||||
# `run_in_actor(trio.sleep_forever)`).
|
|
||||||
portals[name] = await an.start_actor(
|
portals[name] = await an.start_actor(
|
||||||
name=name,
|
name=name, enable_modules=[__name__])
|
||||||
enable_modules=[__name__],
|
|
||||||
)
|
else: # no streaming
|
||||||
|
portals[name] = await an.run_in_actor(
|
||||||
|
trio.sleep_forever, name=name)
|
||||||
|
|
||||||
# wait on last actor to come up
|
# wait on last actor to come up
|
||||||
async with tractor.wait_for_actor(name):
|
async with tractor.wait_for_actor(name):
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ from tractor import (
|
||||||
current_actor,
|
current_actor,
|
||||||
Actor,
|
Actor,
|
||||||
to_asyncio,
|
to_asyncio,
|
||||||
to_actor,
|
|
||||||
RemoteActorError,
|
RemoteActorError,
|
||||||
ContextCancelled,
|
ContextCancelled,
|
||||||
)
|
)
|
||||||
|
|
@ -111,9 +110,8 @@ def test_trio_cancels_aio_on_actor_side(
|
||||||
registry_addrs=[reg_addr],
|
registry_addrs=[reg_addr],
|
||||||
debug_mode=debug_mode,
|
debug_mode=debug_mode,
|
||||||
) as an:
|
) as an:
|
||||||
await to_actor.run(
|
await an.run_in_actor(
|
||||||
trio_cancels_single_aio_task,
|
trio_cancels_single_aio_task,
|
||||||
an=an,
|
|
||||||
infect_asyncio=True,
|
infect_asyncio=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -159,28 +157,6 @@ async def asyncio_actor(
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
@tractor.context
|
|
||||||
async def sleep_forever_aio_ctx(
|
|
||||||
ctx: tractor.Context,
|
|
||||||
expect_err: str = 'trio.Cancelled',
|
|
||||||
) -> None:
|
|
||||||
'''
|
|
||||||
`@context` shim so a parent can spawn a forever-sleeping
|
|
||||||
infected-`asyncio` task via `Portal.open_context()` and cancel it
|
|
||||||
(via `Portal.cancel_actor()` or an enclosing `trio` cancel scope),
|
|
||||||
asserting the graceful `trio.Cancelled` teardown.
|
|
||||||
|
|
||||||
Replaces the legacy `ActorNursery.run_in_actor()` spawn the
|
|
||||||
aio-cancel tests below used to rely on (removed with #477).
|
|
||||||
|
|
||||||
'''
|
|
||||||
await ctx.started()
|
|
||||||
await asyncio_actor(
|
|
||||||
target='aio_sleep_forever',
|
|
||||||
expect_err=expect_err,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_aio_simple_error(
|
def test_aio_simple_error(
|
||||||
reg_addr: tuple[str, int],
|
reg_addr: tuple[str, int],
|
||||||
debug_mode: bool,
|
debug_mode: bool,
|
||||||
|
|
@ -196,9 +172,8 @@ def test_aio_simple_error(
|
||||||
registry_addrs=[reg_addr],
|
registry_addrs=[reg_addr],
|
||||||
debug_mode=debug_mode,
|
debug_mode=debug_mode,
|
||||||
) as an:
|
) as an:
|
||||||
await to_actor.run(
|
await an.run_in_actor(
|
||||||
asyncio_actor,
|
asyncio_actor,
|
||||||
an=an,
|
|
||||||
target='sleep_and_err',
|
target='sleep_and_err',
|
||||||
expect_err='AssertionError',
|
expect_err='AssertionError',
|
||||||
infect_asyncio=True,
|
infect_asyncio=True,
|
||||||
|
|
@ -232,34 +207,18 @@ def test_tractor_cancels_aio(
|
||||||
|
|
||||||
'''
|
'''
|
||||||
async def main():
|
async def main():
|
||||||
# anti-hang wall-clock cap: a per-test `trio.fail_after`
|
|
||||||
# is the blessed guard here since `pytest-timeout`'s
|
|
||||||
# global cap is intentionally off (see the `pyproject`
|
|
||||||
# NOTE — it breaks trio under fork backends). Generous +
|
|
||||||
# CPU-headroom-scaled bc this is an anti-hang guard, not
|
|
||||||
# a perf assertion; a wedged ria-reaper once hung this
|
|
||||||
# test forever (the `._ria_nursery`-removal regression).
|
|
||||||
from .conftest import cpu_perf_headroom
|
|
||||||
with trio.fail_after(9 * cpu_perf_headroom()):
|
|
||||||
async with tractor.open_nursery(
|
async with tractor.open_nursery(
|
||||||
debug_mode=debug_mode,
|
debug_mode=debug_mode,
|
||||||
registry_addrs=[reg_addr],
|
registry_addrs=[reg_addr],
|
||||||
) as an:
|
) as an:
|
||||||
p: tractor.Portal = await an.start_actor(
|
portal = await an.run_in_actor(
|
||||||
'aio_daemon',
|
asyncio_actor,
|
||||||
enable_modules=[__name__],
|
target='aio_sleep_forever',
|
||||||
|
expect_err='trio.Cancelled',
|
||||||
infect_asyncio=True,
|
infect_asyncio=True,
|
||||||
)
|
)
|
||||||
async with (
|
# cancel the entire remote runtime
|
||||||
# `.cancel_actor()` below tears the ctx down
|
await portal.cancel_actor()
|
||||||
expect_ctxc(yay=True),
|
|
||||||
p.open_context(
|
|
||||||
sleep_forever_aio_ctx,
|
|
||||||
) as (ctx, first),
|
|
||||||
):
|
|
||||||
# cancel the entire remote runtime while its
|
|
||||||
# infected-`asyncio` task sleeps forever
|
|
||||||
await p.cancel_actor()
|
|
||||||
|
|
||||||
trio.run(main)
|
trio.run(main)
|
||||||
|
|
||||||
|
|
@ -277,19 +236,13 @@ def test_trio_cancels_aio(
|
||||||
with trio.move_on_after(1):
|
with trio.move_on_after(1):
|
||||||
async with tractor.open_nursery(
|
async with tractor.open_nursery(
|
||||||
registry_addrs=[reg_addr],
|
registry_addrs=[reg_addr],
|
||||||
) as an:
|
) as tn:
|
||||||
p: tractor.Portal = await an.start_actor(
|
await tn.run_in_actor(
|
||||||
'aio_daemon',
|
asyncio_actor,
|
||||||
enable_modules=[__name__],
|
target='aio_sleep_forever',
|
||||||
|
expect_err='trio.Cancelled',
|
||||||
infect_asyncio=True,
|
infect_asyncio=True,
|
||||||
)
|
)
|
||||||
async with p.open_context(
|
|
||||||
sleep_forever_aio_ctx,
|
|
||||||
) as (ctx, first):
|
|
||||||
# block until the enclosing `move_on_after`
|
|
||||||
# cancels this `trio` scope, tearing down the
|
|
||||||
# infected-aio task via ctx cancellation
|
|
||||||
await trio.sleep_forever()
|
|
||||||
|
|
||||||
trio.run(main)
|
trio.run(main)
|
||||||
|
|
||||||
|
|
@ -439,16 +392,17 @@ def test_aio_cancelled_from_aio_causes_trio_cancelled(
|
||||||
async with tractor.open_nursery(
|
async with tractor.open_nursery(
|
||||||
registry_addrs=[reg_addr],
|
registry_addrs=[reg_addr],
|
||||||
) as an:
|
) as an:
|
||||||
# `to_actor.run()` blocks on the one-shot's result and
|
p: tractor.Portal = await an.run_in_actor(
|
||||||
# relays the remote error here in the caller's task.
|
|
||||||
with trio.fail_after(1 + delay):
|
|
||||||
await to_actor.run(
|
|
||||||
asyncio_actor,
|
asyncio_actor,
|
||||||
an=an,
|
|
||||||
target='aio_cancel',
|
target='aio_cancel',
|
||||||
expect_err='tractor.to_asyncio.AsyncioCancelled',
|
expect_err='tractor.to_asyncio.AsyncioCancelled',
|
||||||
infect_asyncio=True,
|
infect_asyncio=True,
|
||||||
)
|
)
|
||||||
|
# NOTE: normally the `an.__aexit__()` waits on the
|
||||||
|
# portal's result but we do it explicitly here
|
||||||
|
# to avoid indent levels.
|
||||||
|
with trio.fail_after(1 + delay):
|
||||||
|
await p.wait_for_result()
|
||||||
|
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
expected_exception=(RemoteActorError, ExceptionGroup),
|
expected_exception=(RemoteActorError, ExceptionGroup),
|
||||||
|
|
@ -649,13 +603,13 @@ def test_basic_interloop_channel_stream(
|
||||||
async with tractor.open_nursery(
|
async with tractor.open_nursery(
|
||||||
registry_addrs=[reg_addr],
|
registry_addrs=[reg_addr],
|
||||||
) as an:
|
) as an:
|
||||||
# should raise RAE diectly
|
portal = await an.run_in_actor(
|
||||||
await to_actor.run(
|
|
||||||
stream_from_aio,
|
stream_from_aio,
|
||||||
an=an,
|
|
||||||
infect_asyncio=True,
|
infect_asyncio=True,
|
||||||
fan_out=fan_out,
|
fan_out=fan_out,
|
||||||
)
|
)
|
||||||
|
# should raise RAE diectly
|
||||||
|
await portal.result()
|
||||||
|
|
||||||
trio.run(main)
|
trio.run(main)
|
||||||
|
|
||||||
|
|
@ -668,13 +622,13 @@ def test_trio_error_cancels_intertask_chan(
|
||||||
async with tractor.open_nursery(
|
async with tractor.open_nursery(
|
||||||
registry_addrs=[reg_addr],
|
registry_addrs=[reg_addr],
|
||||||
) as an:
|
) as an:
|
||||||
# should trigger remote actor error
|
portal = await an.run_in_actor(
|
||||||
await to_actor.run(
|
|
||||||
stream_from_aio,
|
stream_from_aio,
|
||||||
an=an,
|
|
||||||
trio_raise_err=True,
|
trio_raise_err=True,
|
||||||
infect_asyncio=True,
|
infect_asyncio=True,
|
||||||
)
|
)
|
||||||
|
# should trigger remote actor error
|
||||||
|
await portal.result()
|
||||||
|
|
||||||
with pytest.raises(RemoteActorError) as excinfo:
|
with pytest.raises(RemoteActorError) as excinfo:
|
||||||
trio.run(main)
|
trio.run(main)
|
||||||
|
|
@ -704,14 +658,14 @@ def test_trio_closes_early_causes_aio_checkpoint_raise(
|
||||||
# enable_stack_on_sig=True,
|
# enable_stack_on_sig=True,
|
||||||
registry_addrs=[reg_addr],
|
registry_addrs=[reg_addr],
|
||||||
) as an:
|
) as an:
|
||||||
# should raise RAE diectly
|
portal = await an.run_in_actor(
|
||||||
print('waiting on final infected subactor result..')
|
|
||||||
res: None = await to_actor.run(
|
|
||||||
stream_from_aio,
|
stream_from_aio,
|
||||||
an=an,
|
|
||||||
trio_exit_early=True,
|
trio_exit_early=True,
|
||||||
infect_asyncio=True,
|
infect_asyncio=True,
|
||||||
)
|
)
|
||||||
|
# should raise RAE diectly
|
||||||
|
print('waiting on final infected subactor result..')
|
||||||
|
res: None = await portal.wait_for_result()
|
||||||
assert res is None
|
assert res is None
|
||||||
print(f'infected subactor returned result: {res!r}\n')
|
print(f'infected subactor returned result: {res!r}\n')
|
||||||
|
|
||||||
|
|
@ -755,15 +709,15 @@ def test_aio_exits_early_relays_AsyncioTaskExited(
|
||||||
debug_mode=debug_mode,
|
debug_mode=debug_mode,
|
||||||
# enable_stack_on_sig=True,
|
# enable_stack_on_sig=True,
|
||||||
) as an:
|
) as an:
|
||||||
# should raise RAE diectly
|
portal = await an.run_in_actor(
|
||||||
print('waiting on final infected subactor result..')
|
|
||||||
res: None = await to_actor.run(
|
|
||||||
stream_from_aio,
|
stream_from_aio,
|
||||||
an=an,
|
|
||||||
infect_asyncio=True,
|
infect_asyncio=True,
|
||||||
trio_exit_early=False,
|
trio_exit_early=False,
|
||||||
aio_exit_early=True,
|
aio_exit_early=True,
|
||||||
)
|
)
|
||||||
|
# should raise RAE diectly
|
||||||
|
print('waiting on final infected subactor result..')
|
||||||
|
res: None = await portal.wait_for_result()
|
||||||
assert res is None
|
assert res is None
|
||||||
print(f'infected subactor returned result: {res!r}\n')
|
print(f'infected subactor returned result: {res!r}\n')
|
||||||
|
|
||||||
|
|
@ -795,19 +749,17 @@ def test_aio_errors_and_channel_propagates_and_closes(
|
||||||
registry_addrs=[reg_addr],
|
registry_addrs=[reg_addr],
|
||||||
debug_mode=debug_mode,
|
debug_mode=debug_mode,
|
||||||
) as an:
|
) as an:
|
||||||
# should trigger RAE directly, not an eg.
|
portal = await an.run_in_actor(
|
||||||
await to_actor.run(
|
|
||||||
stream_from_aio,
|
stream_from_aio,
|
||||||
an=an,
|
|
||||||
aio_raise_err=True,
|
aio_raise_err=True,
|
||||||
infect_asyncio=True,
|
infect_asyncio=True,
|
||||||
)
|
)
|
||||||
|
# should trigger RAE directly, not an eg.
|
||||||
|
await portal.result()
|
||||||
|
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
# NOTE: bc `to_actor.run()` blocks on + relays the result
|
# NOTE: bc we directly wait on `Portal.result()` instead
|
||||||
# in the caller's task (not captured inside the
|
# of capturing it inside the `ActorNursery` machinery.
|
||||||
# `ActorNursery` teardown machinery) we get a direct RAE,
|
|
||||||
# not an eg.
|
|
||||||
expected_exception=RemoteActorError,
|
expected_exception=RemoteActorError,
|
||||||
) as excinfo:
|
) as excinfo:
|
||||||
trio.run(main)
|
trio.run(main)
|
||||||
|
|
|
||||||
|
|
@ -176,13 +176,10 @@ def test_multi_actor_subs_arbiter_pub(
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
|
|
||||||
async with (
|
async with tractor.open_nursery(
|
||||||
tractor.open_nursery(
|
|
||||||
registry_addrs=[reg_addr],
|
registry_addrs=[reg_addr],
|
||||||
enable_modules=[__name__],
|
enable_modules=[__name__],
|
||||||
) as n,
|
) as n:
|
||||||
trio.open_nursery() as tn,
|
|
||||||
):
|
|
||||||
|
|
||||||
name = 'root'
|
name = 'root'
|
||||||
|
|
||||||
|
|
@ -194,37 +191,18 @@ def test_multi_actor_subs_arbiter_pub(
|
||||||
)
|
)
|
||||||
name = 'streamer'
|
name = 'streamer'
|
||||||
|
|
||||||
# spawn the two subscriber actors as daemons and run
|
even_portal = await n.run_in_actor(
|
||||||
# `subs()` on each as a background task (was the legacy
|
|
||||||
# `run_in_actor()`); keep the portals for the explicit
|
|
||||||
# `cancel_actor()` teardown below. Each runner swallows
|
|
||||||
# the teardown error that `cancel_actor()` relays.
|
|
||||||
async def _run_subs(
|
|
||||||
portal: tractor.Portal,
|
|
||||||
which: list[str],
|
|
||||||
) -> None:
|
|
||||||
try:
|
|
||||||
await portal.run(
|
|
||||||
subs,
|
subs,
|
||||||
which=which,
|
which=['even'],
|
||||||
pub_actor_name=name,
|
name='evens',
|
||||||
|
pub_actor_name=name
|
||||||
)
|
)
|
||||||
except (
|
odd_portal = await n.run_in_actor(
|
||||||
tractor.RemoteActorError,
|
subs,
|
||||||
tractor.ContextCancelled,
|
which=['odd'],
|
||||||
):
|
name='odds',
|
||||||
pass # expected once we `cancel_actor()` below
|
pub_actor_name=name
|
||||||
|
|
||||||
even_portal = await n.start_actor(
|
|
||||||
'evens',
|
|
||||||
enable_modules=[__name__],
|
|
||||||
)
|
)
|
||||||
odd_portal = await n.start_actor(
|
|
||||||
'odds',
|
|
||||||
enable_modules=[__name__],
|
|
||||||
)
|
|
||||||
tn.start_soon(_run_subs, even_portal, ['even'])
|
|
||||||
tn.start_soon(_run_subs, odd_portal, ['odd'])
|
|
||||||
|
|
||||||
async with tractor.wait_for_actor('evens'):
|
async with tractor.wait_for_actor('evens'):
|
||||||
# block until 2nd actor is initialized
|
# block until 2nd actor is initialized
|
||||||
|
|
@ -279,9 +257,6 @@ def test_multi_actor_subs_arbiter_pub(
|
||||||
else:
|
else:
|
||||||
await master_portal.cancel_actor()
|
await master_portal.cancel_actor()
|
||||||
|
|
||||||
# drop the bg `subs()` runners now the subs are cancelled
|
|
||||||
tn.cancel_scope.cancel()
|
|
||||||
|
|
||||||
trio.run(main)
|
trio.run(main)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -111,9 +111,8 @@ def test_rpc_errors(
|
||||||
|
|
||||||
actor = tractor.current_actor()
|
actor = tractor.current_actor()
|
||||||
assert actor.is_registrar
|
assert actor.is_registrar
|
||||||
await tractor.to_actor.run(
|
await n.run_in_actor(
|
||||||
sleep_back_actor,
|
sleep_back_actor,
|
||||||
an=n,
|
|
||||||
actor_name=subactor_requests_to,
|
actor_name=subactor_requests_to,
|
||||||
|
|
||||||
name='subactor',
|
name='subactor',
|
||||||
|
|
|
||||||
|
|
@ -78,12 +78,13 @@ async def test_lifetime_stack_wipes_tmpfile(
|
||||||
async with tractor.open_nursery(
|
async with tractor.open_nursery(
|
||||||
loglevel=loglevel,
|
loglevel=loglevel,
|
||||||
) as an:
|
) as an:
|
||||||
await tractor.to_actor.run(
|
await ( # inlined `tractor.Portal`
|
||||||
|
await an.run_in_actor(
|
||||||
crash_and_clean_tmpdir,
|
crash_and_clean_tmpdir,
|
||||||
an=an,
|
|
||||||
tmp_file_path=path,
|
tmp_file_path=path,
|
||||||
error=error_in_child,
|
error=error_in_child,
|
||||||
)
|
)
|
||||||
|
).result()
|
||||||
except (
|
except (
|
||||||
tractor.RemoteActorError,
|
tractor.RemoteActorError,
|
||||||
BaseExceptionGroup,
|
BaseExceptionGroup,
|
||||||
|
|
|
||||||
|
|
@ -48,11 +48,9 @@ async def spawn(
|
||||||
actor: tractor.Actor = tractor.current_actor()
|
actor: tractor.Actor = tractor.current_actor()
|
||||||
assert actor.is_registrar == should_be_root
|
assert actor.is_registrar == should_be_root
|
||||||
|
|
||||||
# recursively spawn this same `spawn()` fn as the lone
|
# spawns subproc here
|
||||||
# task of a one-shot child subactor and get its result.
|
portal: tractor.Portal = await an.run_in_actor(
|
||||||
result = await tractor.to_actor.run(
|
fn=spawn,
|
||||||
spawn,
|
|
||||||
an=an,
|
|
||||||
|
|
||||||
# spawning args
|
# spawning args
|
||||||
name='sub-actor',
|
name='sub-actor',
|
||||||
|
|
@ -64,6 +62,16 @@ async def spawn(
|
||||||
data=data_to_pass_down,
|
data=data_to_pass_down,
|
||||||
reg_addr=reg_addr,
|
reg_addr=reg_addr,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
assert len(an._children) == 1
|
||||||
|
assert (
|
||||||
|
portal.channel.aid.uid
|
||||||
|
in
|
||||||
|
tractor.current_actor().ipc_server._peers
|
||||||
|
)
|
||||||
|
|
||||||
|
# get result from child subactor
|
||||||
|
result = await portal.result()
|
||||||
assert result == 10
|
assert result == 10
|
||||||
return result
|
return result
|
||||||
else:
|
else:
|
||||||
|
|
@ -71,7 +79,7 @@ async def spawn(
|
||||||
return 10
|
return 10
|
||||||
|
|
||||||
|
|
||||||
def test_to_actor_run_same_func_in_child(
|
def test_run_in_actor_same_func_in_child(
|
||||||
reg_addr: tuple,
|
reg_addr: tuple,
|
||||||
debug_mode: bool,
|
debug_mode: bool,
|
||||||
):
|
):
|
||||||
|
|
@ -151,16 +159,21 @@ async def test_most_beautiful_word(
|
||||||
async with tractor.open_nursery(
|
async with tractor.open_nursery(
|
||||||
debug_mode=debug_mode,
|
debug_mode=debug_mode,
|
||||||
) as an:
|
) as an:
|
||||||
res: Any = await tractor.to_actor.run(
|
portal = await an.run_in_actor(
|
||||||
cellar_door,
|
cellar_door,
|
||||||
an=an,
|
|
||||||
return_value=return_value,
|
return_value=return_value,
|
||||||
name='some_linguist',
|
name='some_linguist',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
res: Any = await portal.wait_for_result()
|
||||||
|
assert res == return_value
|
||||||
|
# The ``async with`` will unblock here since the 'some_linguist'
|
||||||
|
# actor has completed its main task ``cellar_door``.
|
||||||
|
|
||||||
|
# this should pull the cached final result already captured during
|
||||||
|
# the nursery block exit.
|
||||||
|
res: Any = await portal.wait_for_result()
|
||||||
assert res == return_value
|
assert res == return_value
|
||||||
# The ``async with`` unblocks here — the 'some_linguist'
|
|
||||||
# one-shot actor completed its lone task ``cellar_door`` and
|
|
||||||
# was reaped by `to_actor.run()`.
|
|
||||||
print(res)
|
print(res)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -203,9 +216,8 @@ def test_loglevel_propagated_to_subactor(
|
||||||
registry_addrs=[reg_addr],
|
registry_addrs=[reg_addr],
|
||||||
|
|
||||||
) as tn:
|
) as tn:
|
||||||
await tractor.to_actor.run(
|
await tn.run_in_actor(
|
||||||
check_loglevel,
|
check_loglevel,
|
||||||
an=tn,
|
|
||||||
loglevel=level,
|
loglevel=level,
|
||||||
level=level,
|
level=level,
|
||||||
)
|
)
|
||||||
|
|
@ -255,11 +267,11 @@ async def check_parent_main_inheritance(
|
||||||
return has_data
|
return has_data
|
||||||
|
|
||||||
|
|
||||||
def test_to_actor_run_can_skip_parent_main_inheritance(
|
def test_run_in_actor_can_skip_parent_main_inheritance(
|
||||||
start_method: str, # <- only support on `trio` backend rn.
|
start_method: str, # <- only support on `trio` backend rn.
|
||||||
):
|
):
|
||||||
'''
|
'''
|
||||||
Verify ``inherit_parent_main=False`` on ``to_actor.run()``
|
Verify ``inherit_parent_main=False`` on ``run_in_actor()``
|
||||||
prevents parent ``__main__`` data from reaching the child.
|
prevents parent ``__main__`` data from reaching the child.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
@ -272,21 +284,21 @@ def test_to_actor_run_can_skip_parent_main_inheritance(
|
||||||
async with tractor.open_nursery(start_method='trio') as an:
|
async with tractor.open_nursery(start_method='trio') as an:
|
||||||
|
|
||||||
# Default: child receives parent __main__ bootstrap data
|
# Default: child receives parent __main__ bootstrap data
|
||||||
await tractor.to_actor.run(
|
replaying = await an.run_in_actor(
|
||||||
check_parent_main_inheritance,
|
check_parent_main_inheritance,
|
||||||
an=an,
|
|
||||||
name='replaying-parent-main',
|
name='replaying-parent-main',
|
||||||
expect_inherited=True,
|
expect_inherited=True,
|
||||||
)
|
)
|
||||||
|
await replaying.result()
|
||||||
|
|
||||||
# Opt-out: child gets no parent __main__ data
|
# Opt-out: child gets no parent __main__ data
|
||||||
await tractor.to_actor.run(
|
isolated = await an.run_in_actor(
|
||||||
check_parent_main_inheritance,
|
check_parent_main_inheritance,
|
||||||
an=an,
|
|
||||||
name='isolated-parent-main',
|
name='isolated-parent-main',
|
||||||
inherit_parent_main=False,
|
inherit_parent_main=False,
|
||||||
expect_inherited=False,
|
expect_inherited=False,
|
||||||
)
|
)
|
||||||
|
await isolated.result()
|
||||||
|
|
||||||
trio.run(main)
|
trio.run(main)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue