Add tractor.to_actor one-shot task API subpkg#481
Open
goodboy wants to merge 3 commits into
Open
Conversation
First cut at the `to_thread`/`to_process`-style "run it over there" wrapper layer from issue #477: a single-remote-task invocation API decoupled from the `ActorNursery` spawn machinery, composed purely from the lower level daemon-actor + portal primitives, - `to_actor.run(fn, **fn_kwargs)` spawns a subactor via `ActorNursery.start_actor()`, schedules `fn` as its lone task with `Portal.run()` and ALWAYS reaps it via a `finally`-scoped `Portal.cancel_actor()` (whose bounded cancel-req wait is internally shielded so the reap also runs under caller-scope cancellation). - remote errors raise directly in the caller's task as boxed `RemoteActorError`s, moving error collection/propagation up into whatever local `trio` scope encloses the call. - "placement" opts: `portal=` reuses a running actor (no spawn/reap), `an=` spawns from a caller-managed actor-nursery, neither opens a private call-scoped `open_nursery()` (implicitly booting the runtime, tunable via pass-through `runtime_kwargs`). - fail-fast validation BEFORE any spawn: non-streaming async fn only (same constraint as `Portal.run()`), `portal=`/`an=` mutual exclusion and no `runtime_kwargs` alongside a placement opt. Also, - x-ref the successor API from `.run_in_actor()`'s deprecation TODO + docstring; emitting a formal `DeprecationWarning` waits on migrating in-repo usage. - log prompt-io provenance per NLNet policy incl. the driver prompt file. Prompt-IO: ai/prompt-io/claude/20260702T154255Z_65bf9df5_prompt_io.md (this patch was generated in some part by [`claude-code`][claude-code-gh]) [claude-code-gh]: https://github.com/anthropics/claude-code
Cover every placement variant + failure mode of the new `to_actor.run()`, - private-nursery one-shot + implicit runtime boot via pass-through `runtime_kwargs`, - remote-error relay to the caller's task (bare and inside a caller-managed `an`) as boxed `RemoteActorError`s, - caller-nursery spawn + portal-reuse w/o implicit reap, - the concurrent "worker-pool-ish" pattern: a local `trio` task nursery scheduling one-shots against a shared `an`, - the 4 pre-spawn validation rejections (sync fn, async-gen fn, `portal`+`an` combo, `runtime_kwargs`+placement combo). (this patch was generated in some part by [`claude-code`][claude-code-gh]) [claude-code-gh]: https://github.com/anthropics/claude-code
Demo both flavors of the new API in a runnable script (auto-collected by `test_docs_examples.py`), - the fully-implicit one-shot which boots (and tears down) the actor-runtime around a single `to_actor.run()` call, - the concurrent "worker-pool-ish" prime-check pattern: a local `trio` task nursery scheduling one-shots against a shared caller-managed `an`, mirroring (in miniature) the neighboring `concurrent_actors_primes.py` example per issue #477. (this patch was generated in some part by [`claude-code`][claude-code-gh]) [claude-code-gh]: https://github.com/anthropics/claude-code
There was a problem hiding this comment.
Pull request overview
Introduces a new tractor.to_actor subpackage providing a high-level, “one-shot” remote task invocation API built on existing ActorNursery.start_actor() + Portal.run() + Portal.cancel_actor() primitives, intended as the successor to ActorNursery.run_in_actor() (issue #477).
Changes:
- Adds
tractor.to_actor.run()implementing one-shot subactor spawn/reuse, remote execution, and teardown behavior. - Exposes the new subpackage at the top level (
import tractor.to_actor) and documents the intended migration path fromrun_in_actor(). - Adds a dedicated test suite and a runnable example demonstrating concurrent one-shot usage patterns.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tractor/to_actor/_api.py | Implements the new to_actor.run() API and its helper routines. |
| tractor/to_actor/init.py | Defines the new tractor.to_actor public surface (re-export of run). |
| tractor/runtime/_supervise.py | Updates run_in_actor() notes/TODOs to point to the successor API. |
| tractor/init.py | Re-exports to_actor at the package top level. |
| tests/test_to_actor.py | Adds coverage for placement modes, error propagation, concurrency pattern, and validation. |
| examples/parallelism/to_actor_one_shots.py | Adds an example demonstrating implicit runtime boot and concurrent one-shots. |
| ai/prompt-io/prompts/issue_477.md | Adds the driver prompt used for the work. |
| ai/prompt-io/claude/20260702T154255Z_65bf9df5_prompt_io.raw.md | Adds raw AI output log for the work session. |
| ai/prompt-io/claude/20260702T154255Z_65bf9df5_prompt_io.md | Adds summarized AI output log for the work session. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+105
to
+112
| finally: | ||
| # one-shot semantics: the subactor's lifetime is | ||
| # bound to its lone task's completion; the | ||
| # cancel-req's bounded wait is shielded | ||
| # internally (see `Portal.cancel_actor()`) so | ||
| # this reap also runs when the caller's scope | ||
| # was itself cancelled. | ||
| await portal.cancel_actor() |
Comment on lines
+1
to
+3
| NOTE: you MUST pause this work at 12:50PM EST (BEFORE your weekly | ||
| limit reset) for review by a human! | ||
|
|
tractor.to_actor one-shot task API subpkg
5cd190c to
a34aaf9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add
tractor.to_actorone-shot task API subpkgMotivation
First cut at resolving #477: the
.run_in_actor()"one shot"single-remote-task style API is coupled to
ActorNurseryinternals(the secondary
._ria_nursery, portal result-marking sets andbackend-side reaper tasks) which complicates the spawn and
cancellation machinery and defers remote-error propagation to nursery
teardown. Adopting the parlance of sibling APIs (
trio.to_thread,anyio.to_process) we instead deliver atractor.to_actorsubpkgcomposed purely from the lower level daemon-spawn + portal
primitives, moving error collection/propagation up into whatever
local
trioscope encloses the call — and paving the way to fullydrop the
._ria_nurserymachinery.Summary of changes
tractor.to_actorsubpkg exportingrun(fn, **fn_kwargs) -> Any: spawn a subactor viaActorNursery.start_actor(), schedulefnas its lone remote task withPortal.run(), block waiting onand return its result, ALWAYS reaping the subactor via a
finally-scopedPortal.cancel_actor(). Remote errors raisedirectly in the caller's task as boxed
RemoteActorErrors."Placement" opts:
portal=re-uses a running actor (nospawn/reap),
an=spawns from a caller-managed actor-nursery,neither opens a private call-scoped
open_nursery()(implicitlybooting the runtime, tunable via pass-through
runtime_kwargs).Fail-fast pre-spawn validation: non-streaming async fn only,
portal=/an=mutually exclusive, noruntime_kwargsalongside aplacement opt. Legacy
.run_in_actor()behavior untouched; itsTODO/docstring now x-ref the successor API.
tests/test_to_actor.py: 11-test suite covering all placementvariants, remote-error relay (bare + inside a caller-managed
an),portal re-use w/o implicit reap, the concurrent "worker-pool-ish"
pattern (local
triotask nursery scheduling one-shots against ashared
an) and the 4 validation rejections.examples/parallelism/to_actor_one_shots.py: runnable demo(auto-collected by
test_docs_examples.py) of the fully-implicitone-shot + the concurrent prime-check pattern, a mini version of
the neighboring
concurrent_actors_primes.py.Future follow up
Tracked in #477 (see the landed-shape comment there),
.run_in_actor()usage (tests, examples, docs)to
to_actor.run()DeprecationWarningfrom.run_in_actor()(blocked on^)
._ria_nursery+._cancel_after_result_on_exitmachinery — in progress on the stacked
drop_ria_nurserybranch(result-waiting being re-scoped into the
to_actorlayer), seeai/conc-anal/ria_nursery_removal_plan.md.run_in_actor()autodoc entry.run_in_actor()? #172)(this pr content was generated in some part by
claude-code)