Compare commits

...

3 Commits

Author SHA1 Message Date
Gud Boi c62f93a8fb Doc the #477 migration outcome + one-shot-acm sketch
Fold the endeavour's resolution into the plan doc + log the
session per prompt-io policy,

- `ria_nursery_removal_plan.md`: RESOLVED section — migrate
  everything, remove the API; the migration-pattern table
  (blocking / fire-and-forget / fan-out / collect-don't-cancel
  / mutual-rendezvous), the semantic deltas (cancel-on-first +
  `collapse_eg()` chain collapse vs the old teardown-reap BEG),
  the excision inventory and the structural dissolution of the
  reap-hang class.
- adds the `to_actor.open_one_shot()` follow-up sketch: an
  `@acm` + private task-nursery over the existing blocking
  `run()` — done-`trio.Event` as a result memo (NOT a
  cancel-relay), no `Portal` in the iface, errors always
  propagate at scope exit; zero `_supervise` coupling.
- prompt-io entry `20260706T172818Z_ad42871e` (+ raw diff-ref
  companion) covering commits `d01a2123..ad42871e`.

(this patch was generated in some part by [`claude-code`][claude-code-gh])
[claude-code-gh]: https://github.com/anthropics/claude-code
2026-07-06 14:31:34 -04:00
Gud Boi ad42871e47 Name every `ActorNursery` binding `an` in tests/examples
Convention sweep (user req): all `tractor.open_nursery()`
bindings in test + example code use `an: ActorNursery` (`n`,
`nursery` + several tractor-nurseries confusingly named `tn`
are renamed); `trio.open_nursery()` bindings stay `tn` (incl.
`concurrent_actors_primes.py`'s inner trio nursery, renamed
`n` -> `tn` to match).

Purely mechanical, function-scoped renames — prose "nursery"/
"an" in docstrings/comments untouched; func-arg kwargs like
`portal.run(func, n=value)` untouched.

Gate: renamed test modules green on `trio`; full debugger suite
(28p/6s) + example-runner (21p) green.

(this patch was generated in some part by [`claude-code`][claude-code-gh])
[claude-code-gh]: https://github.com/anthropics/claude-code
2026-07-06 13:26:55 -04:00
Gud Boi a297a32af6 Fix mutual-rendezvous premature-reap race (#477)
The `test_trynamic_trio` + `a_trynamic_first_scene.py` migration
to paired `to_actor.run()` one-shots carries a race the legacy
`run_in_actor()` shape never had: donny + gretchen each
`wait_for_actor()` (then DIAL) the *other*, but a one-shot is
reaped the instant its own hello returns — so the slower peer
can resolve the winner's registry entry and connect to an
already-dead sockaddr -> `ConnectionRefusedError` boxed as a
`RemoteActorError` (or a reg-wait `TooSlowError`), flaking
~1-in-3 standalone runs.

Mutual-rendezvous peers must OUTLIVE both dialogs, so pin the
lifetimes explicitly: `start_actor()` both as daemons, run both
hellos concurrently via bg `Portal.run()` tasks, then reap with
`an.cancel()` only after the task-nursery joins. (The legacy
teardown-reap provided this pinning implicitly — one of the
few places its semantics were ever actually relied upon.)

Gate: `-k trynamic` standalone x8 green (was flaking); full
`test_registrar` module + the example-runner green.

(this patch was generated in some part by [`claude-code`][claude-code-gh])
[claude-code-gh]: https://github.com/anthropics/claude-code
2026-07-06 13:21:31 -04:00
27 changed files with 338 additions and 122 deletions

View File

@ -367,9 +367,94 @@ user's failing-test-first convention). The poll-based reap
fix in `_supervise.py` is UNCOMMITTED and likely SUPERSEDED
by the re-scoping — do NOT land it as-is.
## RESOLVED (2026-07-06): migrate everything, remove the API
The PAUSED re-assessment concluded decisively: rather than
re-scope `_reap_ria_portals` (or bolt any hack onto it), the
`run_in_actor()` API itself was REMOVED — its non-blocking
"result at teardown" semantic predates streaming and confused
more than it served. Every in-repo caller was migrated
per-file/-group (each its own commit, each gated):
- tests: `test_infected_asyncio` `test_runtime` `test_rpc`
`test_spawning` `test_pubsub` `test_registrar`
`test_cancellation` (3 groups) `test_advanced_streaming`.
- examples: 4 non-debugging + all 8 `debugging/` REPL scripts
(debugger suite byte-identical green, 28p/6s).
- docs: 8 rst pages + the `experimental/_pubsub` docstring.
Migration patterns (the `run_in_actor` shape -> successor):
- blocking result -> `to_actor.run(fn, an=an, ...)`
- fire-&-forget/forever -> bg `to_actor.run()` task in a local
`trio` task-nursery (or `start_actor`
+ bg `Portal.run()` when a portal
handle is needed)
- concurrent fan-out -> N bg `to_actor.run()` tasks / or
`gather_contexts([p.open_context(..)])`
- reap-all-error-collect -> the "collect don't cancel" pattern:
each one-shot catches + stashes its
`RemoteActorError`, group raised
after the task-nursery joins (see
`examples/debugging/multi_subactors.py`)
- mutual-rendezvous -> peers must OUTLIVE both dialogs:
`start_actor()` daemons + concurrent
`Portal.run()`s + explicit
`an.cancel()` (eager one-shot reap
races the slower peer's dial of the
winner's dead sockaddr; found via
`test_trynamic_trio` flake).
Semantic deltas (tests loosened accordingly):
- teardown-reap-all BEG-of-N is GONE: local task-nurseries are
cancel-on-first, raced siblings' `Cancelled`s are absorbed,
and the runtime's `collapse_eg()` unwraps every single-member
group at each actor boundary — a fully-raced nested tree
relays a bare (annotated) `RemoteActorError` chain.
- `test_multierror_fast_nursery` deleted (pure reap-stress);
`test_nested_multierrors` re-purposed as deep-tree
cancel-cascade stress w/ a race-tolerant shape walk.
Final excision (after zero callers remained): `run_in_actor()`,
`._cancel_after_result_on_exit`, `_reap_ria_portals()`,
`Portal._submit_for_result/._expect_result_ctx/
.wait_for_result()/.result()`, `exhaust_portal()`,
`cancel_on_completion()`, `NoResult` — net -402 lines. The
reap-hang class (unbounded `wait_for_result` in machinery
scope) dissolves structurally: the only result-wait left lives
in the caller's task inside its own cancel-scope; the
`d1fb4a1a` anti-hang guard test passes by construction. The
poll-vs-`proc_waiter` debate is moot as predicted.
## Follow-up sketch: `to_actor.open_one_shot()` (run-async parity)
If deferred-result parity is ever wanted, the design that needs
NO runtime coupling, NO returned `Portal` and NO cancel-relay
`trio.Event` machinery:
async with to_actor.open_one_shot(
fn, an=an, **kws,
) as one_shot:
... # concurrent caller work
val = await one_shot.wait() # optional; errors always
# propagate at scope exit
an `@acm` that opens a private task-nursery, `start_soon`s ONE
task running the existing blocking `run()` and stashes the
value in a slot + sets a done-`trio.Event` (a memo, not a
cancel relay). Cancellation = plain scope-cancel of the acm's
nursery (the parked `Portal.run()` unwinds via `Cancelled`, the
shielded `cancel_actor()` reap still runs); a child error
raises into the acm scope so an un-`wait()`ed one-shot can
never silently drop its error. i.e. the old reaper's job is
done by scoping, not machinery. ~40 lines, all in
`to_actor/_api.py`, zero `_supervise` involvement.
## Verification gate
- `tests/test_cancellation.py test_spawning.py test_local.py
test_rpc.py` on `trio` + `mp_spawn` + `mp_forkserver`
backends, then full suite; `tests/devx/test_debugger.py`
for risk 3.
- per-migration-commit module gates on `trio` (+ `mp_spawn`
spot-gates incl. `test_infected_asyncio` per the B2 lesson);
`tests/devx/test_debugger.py` for the REPL flows.
- full suite on `trio` + `mp_spawn` at branch tip + CI matrix
via draft PR #484.

View File

@ -0,0 +1,81 @@
---
model: claude-fable-5
service: claude
session: 6db64ac6-6986-4505-9343-df4ee31e67db
timestamp: 2026-07-06T17:28:18Z
git_ref: ad42871e
scope: code
substantive: true
raw_file: 20260706T172818Z_ad42871e_prompt_io.raw.md
---
## Prompt
Resuming the `drop_ria_nursery` (wkt) branch after the human's
review pause at `ba4af0ad`, with the directive:
> we need to resolve the remaining outstandings ... to finish
> this endeavour we ideally,
> - finish the ria-tn hoist into the machinery in `to_actor` if
> possible.
> - avoid supporting the `.run_in_actor()` non-blocking API
> going forward other then if we can re-wrap `to_actor.run()`
> per prior discussion with opus4.8.
> - get the test harness completely green locally and in CI -
> AND ESPECIALLY without any hangs due to the "the old
> spawn-backend reaper raced `soft_kill()`'s scope-cancel"
> - update all docs to reflect these changes once we're happy.
plus mid-flight additions:
> make sure both all the test and example code uses the naming
> `an: ActorNursery` for variable names
> where we at in terms of a potential hackaround design for
> supporting a to_actor.run_async() ... without requiring the
> same malarky ... with a `trio.Event` relay ... i'm totes fine
> with rejigging the iface to NOT return a Portal as well.
## Response summary
Completed the entire #477 `run_in_actor` removal on
`drop_ria_nursery` (16 commits this session), gated per-commit:
- ported the remaining `test_cancellation` groups
(`some_cancels_all`, `nested_multierrors`+`spawn_and_error`,
SIGINT + sync-sleep) — one-shots become concurrent
`to_actor.run()` tasks in local task-nurseries; BEG-shape
assertions loosened for cancel-on-first + the runtime's
`collapse_eg()` single-member unwrap (a fully-raced nested
tree relays a bare annotated `RemoteActorError` chain).
- fixed a pre-existing `UnboundLocalError` (`timeout` `match`
had no default arm for non-trio/MTF backends).
- ported `test_dynamic_pub_sub`, 4 non-debugging examples, all
8 `debugging/` examples (debugger suite byte-identical,
28p/6s; `multi_subactors` introduces the "collect don't
cancel" reap-all replacement pattern), 8 docs pages + the
`experimental/_pubsub` docstring.
- EXCISED the API + cluster: `run_in_actor`,
`_reap_ria_portals`, `_cancel_after_result_on_exit`,
`Portal._submit_for_result/_expect_result_ctx/
wait_for_result/result`, `exhaust_portal`,
`cancel_on_completion`, `NoResult` — net -402 lines. The
reap-hang class dissolves structurally (result-waits now only
in caller task-scope).
- found + fixed a real migration race: mutual-rendezvous peers
(`test_trynamic_trio`, `a_trynamic_first_scene.py`) flaked
because an eagerly-reaped one-shot dies while its peer still
dials the registry-resolved (dead) sockaddr — such peers now
pin lifetimes via `start_actor()` + concurrent `Portal.run()`
+ explicit `an.cancel()`.
- `an: ActorNursery` naming sweep across tests/examples (±82
lines, scoped renames, prose untouched).
- parked a `to_actor.open_one_shot()` design sketch (acm +
private task-nursery over blocking `run()`; done-Event as
memo not cancel-relay; no Portal) in the plan doc.
## Files changed
See commits `d01a2123..ad42871e` on `drop_ria_nursery`
(tests, examples, docs, `tractor/{runtime,spawn,to_actor,msg}`
+ `_exceptions/_context/experimental`).

View File

@ -0,0 +1,39 @@
---
model: claude-fable-5
service: claude
timestamp: 2026-07-06T17:28:18Z
git_ref: ad42871e
diff_cmd: git diff ba4af0ad..ad42871e
---
# Raw AI output (diff-ref mode)
This session's output spans the 16 migration/excision commits
`d01a2123..ad42871e` on `drop_ria_nursery`; per diff-ref mode
the verbatim content is reachable via the pointer below.
## Generated files
> `git diff ba4af0ad..ad42871e`
Commit-wise (each `Gate:`-footed msg documents its own module
gate):
- `d01a2123` port `test_some_cancels_all`
- `697c6152` fix unbound `timeout` (non-trio/MTF `match` arm)
- `fa8799d5` port `test_nested_multierrors`
- `f11754ce` port SIGINT + sync-sleep cancel tests
- `cb6202e3` port `test_dynamic_pub_sub`
- `d8af5f12` port non-debugging examples
- `a3057cb2` port debugging examples (+ `test_debugger`
nested-nurseries final-shape expectations)
- `d6bed7c4` port docs (8 rst pages)
- `07e1669e` fix stale `@pub` docstring example
- `2a59cefb` REMOVE `run_in_actor()` + the ria reap cluster
(net -402 lines)
- `a297a32a` fix mutual-rendezvous premature-reap race
- `ad42871e` `an: ActorNursery` naming sweep
Plan/design record updated in
`ai/conc-anal/ria_nursery_removal_plan.md` (RESOLVED section +
the `to_actor.open_one_shot()` follow-up sketch).

View File

@ -17,36 +17,37 @@ async def say_hello(other_actor):
return await portal.run(hi)
async def run_and_print(
an: tractor.ActorNursery,
name: str,
other_actor: str,
):
print(
await tractor.to_actor.run(
say_hello,
an=an,
name=name,
# arguments are always named
other_actor=other_actor,
)
)
async def main():
"""Main tractor entry point, the "master" process (for now
acts as the "director").
"""
async with (
tractor.open_nursery() as an,
trio.open_nursery() as tn,
):
async with tractor.open_nursery() as an:
print("Alright... Action!")
# both actors wait on the *other* to register so their
# one-shots must run concurrently.
tn.start_soon(run_and_print, an, 'donny', 'gretchen')
tn.start_soon(run_and_print, an, 'gretchen', 'donny')
# both actors wait on (then dial!) the *other*, so each
# must outlive both hellos: spawn as daemons, run the
# hellos concurrently, reap only once both complete.
portals: dict[str, tractor.Portal] = {
name: await an.start_actor(
name,
enable_modules=[__name__],
)
for name in ('donny', 'gretchen')
}
async def run_and_print(name: str, other_actor: str):
print(
await portals[name].run(
say_hello,
other_actor=other_actor,
)
)
async with trio.open_nursery() as tn:
tn.start_soon(run_and_print, 'donny', 'gretchen')
tn.start_soon(run_and_print, 'gretchen', 'donny')
await an.cancel()
print("CUTTTT CUUTT CUT!!! Donny!! You're supposed to say...")

View File

@ -12,9 +12,9 @@ async def movie_theatre_question():
async def main():
"""The main ``tractor`` routine.
"""
async with tractor.open_nursery() as n:
async with tractor.open_nursery() as an:
portal = await n.start_actor(
portal = await an.start_actor(
'frank',
# enable the actor to run funcs from this current module
enable_modules=[__name__],

View File

@ -15,9 +15,9 @@ async def stream_forever() -> AsyncIterator[int]:
async def main():
async with tractor.open_nursery() as n:
async with tractor.open_nursery() as an:
portal = await n.start_actor(
portal = await an.start_actor(
'donny',
enable_modules=[__name__],
)

View File

@ -15,10 +15,10 @@ async def name_error():
async def spawn_error():
""""A nested nursery that triggers another ``NameError``.
"""
async with tractor.open_nursery() as n:
async with tractor.open_nursery() as an:
return await tractor.to_actor.run(
name_error,
an=n,
an=an,
name='name_error_1',
)

View File

@ -17,10 +17,10 @@ async def name_error():
async def spawn_error():
""""A nested nursery that triggers another ``NameError``.
"""
async with tractor.open_nursery() as n:
async with tractor.open_nursery() as an:
return await tractor.to_actor.run(
name_error,
an=n,
an=an,
name='name_error_1',
)

View File

@ -21,8 +21,8 @@ async def main() -> None:
async with tractor.open_nursery(
debug_mode=True,
) as n:
portal = await n.start_actor(
) as an:
portal = await an.start_actor(
'ctx_child',
# XXX: we don't enable the current module in order

View File

@ -6,14 +6,14 @@ async def die():
async def main():
async with tractor.open_nursery() as tn:
async with tractor.open_nursery() as an:
debug_actor = await tn.start_actor(
debug_actor = await an.start_actor(
'debugged_boi',
enable_modules=[__name__],
debug_mode=True,
)
crash_boi = await tn.start_actor(
crash_boi = await an.start_actor(
'crash_boi',
enable_modules=[__name__],
# debug_mode=True,

View File

@ -17,11 +17,11 @@ async def main():
tractor.open_nursery(
debug_mode=True,
# loglevel='debug' # ?XXX required?
) as n,
) as an,
trio.open_nursery() as tn,
):
# spawn the actor..
portal = await n.start_actor(
portal = await an.start_actor(
'key_error',
enable_modules=[__name__],
)

View File

@ -74,10 +74,10 @@ async def cancelled_before_pause(
async def main():
async with tractor.open_nursery(
debug_mode=True,
) as n:
) as an:
await tractor.to_actor.run(
cancelled_before_pause,
an=n,
an=an,
)
# ensure the same works in the root actor!

View File

@ -58,8 +58,8 @@ async def main():
debug_mode=True,
enable_transports=[tpt],
loglevel='devx',
) as n:
p = await n.start_actor(
) as an:
p = await an.start_actor(
'bp_boi',
enable_modules=[__name__],
)

View File

@ -17,13 +17,13 @@ async def main():
async with tractor.open_nursery(
debug_mode=True,
loglevel='cancel',
) as n:
) as an:
# parks awaiting a result which only arrives once the
# user quits (`BdbQuit`s) the child's REPL loop.
await tractor.to_actor.run(
breakpoint_forever,
an=n,
an=an,
)

View File

@ -50,8 +50,8 @@ async def trio_to_aio_echo_server(
async def main():
async with tractor.open_nursery() as n:
p = await n.start_actor(
async with tractor.open_nursery() as an:
p = await an.start_actor(
'aio_server',
enable_modules=[__name__],
infect_asyncio=True,

View File

@ -29,9 +29,9 @@ async def main() -> None:
))
await proc.wait()
# await trio.sleep_forever()
# async with tractor.open_nursery() as n:
# async with tractor.open_nursery() as an:
# portal = await n.start_actor(
# portal = await an.start_actor(
# 'rpc_server',
# enable_modules=[__name__],
# )

View File

@ -55,7 +55,7 @@ async def worker_pool(workers=4):
Yes, the workers stay alive (and ready for work) until you close
the context.
"""
async with tractor.open_nursery() as tn:
async with tractor.open_nursery() as an:
portals = []
snd_chan, recv_chan = trio.open_memory_channel(len(PRIMES))
@ -65,7 +65,7 @@ async def worker_pool(workers=4):
# this starts a new sub-actor (process + trio runtime) and
# stores it's "portal" for later use to "submit jobs" (ugh).
portals.append(
await tn.start_actor(
await an.start_actor(
f'worker_{i}',
enable_modules=[__name__],
)
@ -80,10 +80,10 @@ async def worker_pool(workers=4):
async def send_result(func, value, portal):
await snd_chan.send((value, await portal.run(func, n=value)))
async with trio.open_nursery() as n:
async with trio.open_nursery() as tn:
for value, portal in zip(sequence, itertools.cycle(portals)):
n.start_soon(
tn.start_soon(
send_result,
worker_func,
value,
@ -98,7 +98,7 @@ async def worker_pool(workers=4):
yield _map
# tear down all "workers" on pool close
await tn.cancel()
await an.cancel()
async def main():

View File

@ -7,17 +7,17 @@ async def assert_err():
async def main():
async with tractor.open_nursery() as n:
async with tractor.open_nursery() as an:
real_actors = []
for i in range(3):
real_actors.append(await n.start_actor(
real_actors.append(await an.start_actor(
f'actor_{i}',
enable_modules=[__name__],
))
# run one one-shot task actor that will fail immediately;
# its error raises right here in the caller's task..
await tractor.to_actor.run(assert_err, an=n)
await tractor.to_actor.run(assert_err, an=an)
# ..as a ``RemoteActorError`` containing an ``AssertionError``
# and all the other actors have been cancelled

View File

@ -31,9 +31,9 @@ async def simple_rpc(
async def main() -> None:
async with tractor.open_nursery() as n:
async with tractor.open_nursery() as an:
portal = await n.start_actor(
portal = await an.start_actor(
'rpc_server',
enable_modules=[__name__],
)

View File

@ -46,9 +46,9 @@ async def test_reg_then_unreg(
async with tractor.open_nursery(
registry_addrs=[reg_addr],
) as n:
) as an:
portal = await n.start_actor('actor', enable_modules=[__name__])
portal = await an.start_actor('actor', enable_modules=[__name__])
uid = portal.channel.aid.uid
async with tractor.get_registry(reg_addr) as aportal:
@ -62,7 +62,7 @@ async def test_reg_then_unreg(
# XXX: can we figure out what the listen addr will be?
assert sockaddrs
await n.cancel() # tear down nursery
await an.cancel() # tear down nursery
await trio.sleep(0.1)
assert uid not in aportal.actor._registry
@ -89,9 +89,9 @@ async def test_reg_then_unreg_maddr(
async with tractor.open_nursery(
registry_addrs=[maddr_str],
) as n:
) as an:
portal = await n.start_actor(
portal = await an.start_actor(
'actor_maddr',
enable_modules=[__name__],
)
@ -105,7 +105,7 @@ async def test_reg_then_unreg_maddr(
sockaddrs = actor._registry[uid]
assert sockaddrs
await n.cancel()
await an.cancel()
await trio.sleep(0.1)
assert uid not in aportal.actor._registry
@ -152,27 +152,37 @@ async def test_trynamic_trio(
for the directed subs.
'''
async with (
tractor.open_nursery() as n,
trio.open_nursery() as tn,
):
async with tractor.open_nursery() as an:
print("Alright... Action!")
# donny + gretchen each wait on the *other* to register, so
# they must run CONCURRENTLY — schedule both one-shots into a
# local task-nursery (was two non-blocking `run_in_actor()`s).
# donny + gretchen each wait on (then dial!) the *other*, so
# both actors must OUTLIVE both hellos: spawn as daemons and
# only reap after both tasks complete. NB a pair of eagerly
# reaped `to_actor.run()` one-shots races: the first to
# finish dies while the other may still be dialing its
# registry-resolved (now dead) sockaddr -> conn-refused.
portals: dict[str, tractor.Portal] = {
name: await an.start_actor(
name,
enable_modules=[__name__],
)
for name in ('donny', 'gretchen')
}
async def _direct(this_name: str, other_actor: str):
res = await tractor.to_actor.run(
res = await portals[this_name].run(
ria_fn,
an=n,
other_actor=other_actor,
reg_addr=reg_addr,
name=this_name,
)
print(res)
async with trio.open_nursery() as tn:
tn.start_soon(_direct, 'donny', 'gretchen')
tn.start_soon(_direct, 'gretchen', 'donny')
# both hellos have completed; reap the thespians.
await an.cancel()
print("CUTTTT CUUTT CUT!!?! Donny!! You're supposed to say...")

View File

@ -219,7 +219,7 @@ def test_dynamic_pub_sub(
tractor.open_nursery(
registry_addrs=[reg_addr],
debug_mode=debug_mode,
) as n,
) as an,
# bg-schedules the forever-streaming
# one-shots below; the user-cancel raise
# cancels them all, each reaping its
@ -237,7 +237,7 @@ def test_dynamic_pub_sub(
partial(
tractor.to_actor.run,
publisher,
an=n,
an=an,
)
)
@ -249,7 +249,7 @@ def test_dynamic_pub_sub(
partial(
tractor.to_actor.run,
consumer,
an=n,
an=an,
name=f'consumer_{sub}',
subs=[sub],
)
@ -260,7 +260,7 @@ def test_dynamic_pub_sub(
partial(
tractor.to_actor.run,
consumer,
an=n,
an=an,
name='consumer_dynamic',
subs=list(_registry.keys()),
)
@ -370,10 +370,10 @@ def test_reqresp_ontopof_streaming():
timeout = 4
with trio.move_on_after(timeout):
async with tractor.open_nursery() as n:
async with tractor.open_nursery() as an:
# name of this actor will be same as target func
portal = await n.start_actor(
portal = await an.start_actor(
'dual_tasks',
enable_modules=[__name__]
)
@ -436,9 +436,9 @@ def test_sigint_both_stream_types():
async def main():
with trio.fail_after(timeout):
async with tractor.open_nursery() as n:
async with tractor.open_nursery() as an:
# name of this actor will be same as target func
portal = await n.start_actor(
portal = await an.start_actor(
'2_way',
enable_modules=[__name__]
)
@ -551,8 +551,8 @@ def test_local_task_fanout_from_stream(
async with tractor.open_nursery(
debug_mode=debug_mode,
) as tn:
p: tractor.Portal = await tn.start_actor(
) as an:
p: tractor.Portal = await an.start_actor(
'inf_streamer',
enable_modules=[__name__],
)

View File

@ -126,7 +126,7 @@ def test_remote_error(
async def main():
async with tractor.open_nursery(
registry_addrs=[reg_addr],
) as nursery:
) as an:
# `to_actor.run()` blocks on the one-shot's result and
# raises the remote error directly here in the caller's
@ -135,7 +135,7 @@ def test_remote_error(
try:
await tractor.to_actor.run(
assert_err,
an=nursery,
an=an,
name='errorer',
**args
)
@ -248,16 +248,16 @@ def test_cancel_single_subactor(
'''
async with tractor.open_nursery(
registry_addrs=[reg_addr],
) as nursery:
) as an:
portal = await nursery.start_actor(
portal = await an.start_actor(
'nothin', enable_modules=[__name__],
)
assert (await portal.run(do_nothing)) is None
if mechanism == 'nursery_cancel':
# would hang otherwise
await nursery.cancel()
await an.cancel()
else:
raise mechanism
@ -289,8 +289,8 @@ async def test_cancel_infinite_streamer(
trio.fail_after(4),
trio.move_on_after(1) as cancel_scope
):
async with tractor.open_nursery() as n:
portal = await n.start_actor(
async with tractor.open_nursery() as an:
portal = await an.start_actor(
'donny',
enable_modules=[__name__],
)
@ -303,7 +303,7 @@ async def test_cancel_infinite_streamer(
# we support trio's cancellation system
assert cancel_scope.cancelled_caught
assert n.cancel_called
assert an.cancel_called
@pytest.mark.parametrize(
@ -698,7 +698,7 @@ async def test_nested_multierrors(
async with fail_after_w_trace(timeout):
try:
async with (
tractor.open_nursery() as nursery,
tractor.open_nursery() as an,
trio.open_nursery() as tn,
):
for i in range(subactor_breadth):
@ -706,7 +706,7 @@ async def test_nested_multierrors(
partial(
tractor.to_actor.run,
spawn_and_error,
an=nursery,
an=an,
name=f'spawner_{i}',
breadth=subactor_breadth,
depth=depth,
@ -792,8 +792,8 @@ def test_cancel_via_SIGINT(
with trio.fail_after(2):
async with tractor.open_nursery(
registry_addrs=[reg_addr],
) as tn:
await tn.start_actor('sucka')
) as an:
await an.start_actor('sucka')
if 'mp' in start_method:
time.sleep(0.1)
os.kill(pid, signal.SIGINT)
@ -1054,8 +1054,8 @@ def test_fast_graceful_cancel_when_spawn_task_in_soft_proc_wait_for_daemon(
start = time.time()
try:
async with trio.open_nursery() as nurse:
async with tractor.open_nursery() as tn:
p = await tn.start_actor(
async with tractor.open_nursery() as an:
p = await an.start_actor(
'fast_boi',
enable_modules=[__name__],
)

View File

@ -156,8 +156,8 @@ def test_actor_managed_trio_nursery_task_error_cancels_aio(
async def main():
# cancel the nursery shortly after boot
async with tractor.open_nursery() as n:
p = await n.start_actor(
async with tractor.open_nursery() as an:
p = await an.start_actor(
'nursery_mngr',
infect_asyncio=asyncio_mode, # TODO, is this enabling debug mode?
enable_modules=[__name__],

View File

@ -163,12 +163,12 @@ def test_do_not_swallow_error_before_started_by_remote_contextcancelled(
async def main():
async with tractor.open_nursery(
debug_mode=debug_mode,
) as n:
portal = await n.start_actor(
) as an:
portal = await an.start_actor(
'errorer',
enable_modules=[__name__],
)
await n.start_actor(
await an.start_actor(
'sleeper',
enable_modules=[__name__],
)

View File

@ -139,9 +139,9 @@ async def test_required_args(callwith_expecterror):
with pytest.raises(err):
await func(**kwargs)
else:
async with tractor.open_nursery() as n:
async with tractor.open_nursery() as an:
portal = await n.start_actor(
portal = await an.start_actor(
name='pubber',
enable_modules=[__name__],
)
@ -180,7 +180,7 @@ def test_multi_actor_subs_arbiter_pub(
tractor.open_nursery(
registry_addrs=[reg_addr],
enable_modules=[__name__],
) as n,
) as an,
trio.open_nursery() as tn,
):
@ -188,7 +188,7 @@ def test_multi_actor_subs_arbiter_pub(
if pub_actor == 'streamer':
# start the publisher as a daemon
master_portal = await n.start_actor(
master_portal = await an.start_actor(
'streamer',
enable_modules=[__name__],
)
@ -215,11 +215,11 @@ def test_multi_actor_subs_arbiter_pub(
):
pass # expected once we `cancel_actor()` below
even_portal = await n.start_actor(
even_portal = await an.start_actor(
'evens',
enable_modules=[__name__],
)
odd_portal = await n.start_actor(
odd_portal = await an.start_actor(
'odds',
enable_modules=[__name__],
)
@ -294,9 +294,9 @@ def test_single_subactor_pub_multitask_subs(
async with tractor.open_nursery(
registry_addrs=[reg_addr],
enable_modules=[__name__],
) as n:
) as an:
portal = await n.start_actor(
portal = await an.start_actor(
'streamer',
enable_modules=[__name__],
)

View File

@ -107,13 +107,13 @@ def test_rpc_errors(
# do that if actually debugging subactor but keep it
# disabled for the test.
# debug_mode=True,
) as n:
) as an:
actor = tractor.current_actor()
assert actor.is_registrar
await tractor.to_actor.run(
sleep_back_actor,
an=n,
an=an,
actor_name=subactor_requests_to,
name='subactor',

View File

@ -202,10 +202,10 @@ def test_loglevel_propagated_to_subactor(
start_method=start_method,
registry_addrs=[reg_addr],
) as tn:
) as an:
await tractor.to_actor.run(
check_loglevel,
an=tn,
an=an,
loglevel=level,
level=level,
)