Write the big boi docs content tree
Replace the ancient `docs/index.rst` (still teaching
`tractor.run()`, `@stream` + arbiters..) with a full ~32 page tree
teaching ONLY the current api (`.wait_for_result()`, registrar
naming, `@context` + `open_context()` as the core model),
- landing: hero example, feature cards + canon links,
- `start/`: install + a 4-example quickstart on-ramp,
- `explain/`: an "SC across processes" essay distilling the essence
per #157's orig ask + a runtime architecture tour,
- `guide/`: 12 task-focused pages incl the flagship multi-process
debugging walkthrough, `Context` + `MsgStream` deep-dives,
cancellation semantics (self-vs-cross cancel rules), discovery,
infected `asyncio`, typed msging + the #126 testing-tips page,
- `api/`: 10 curated autodoc pages (all targets import-verified vs
the reorg'd subpkg tree),
- `project/`: changelog include, ported dev-tips (drops old
`docs/dev_tips.rst`) + roadmap.
Every code block is a `literalinclude` from `examples/`
- zero duplication, all CI-run - w/ `d2` figs floated
into the RHS margin per the 3-col design. Build is green; the 24
remaining warnings all source from lib docstring rst-isms or legacy
`NEWS.rst` content.
Substantially resolves #157 (refine round pending); chips at #175 +
#126.
Prompt-IO: ai/prompt-io/claude/20260611T175152Z_8526985c_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
2026-06-11 19:17:14 +00:00
|
|
|
Quickstart
|
|
|
|
|
==========
|
|
|
|
|
Time to spawn something B)
|
|
|
|
|
|
|
|
|
|
If you take one thing from this page make it this: ``tractor``
|
|
|
|
|
**is just** ``trio`` - but with nurseries for process management
|
|
|
|
|
and cancel-able streaming IPC. Every "*actor*" you'll meet below
|
|
|
|
|
is a plain Python **process** running its own ``trio.run()``
|
|
|
|
|
scheduled task tree, linked back to its parent through an IPC
|
|
|
|
|
protocol which keeps the whole tree `structured concurrency`_
|
|
|
|
|
(SC) compliant end-to-end. If you know your nursery_ semantics
|
|
|
|
|
you already know most of ``tractor``; we just stretch them across
|
|
|
|
|
the process boundary.
|
|
|
|
|
|
|
|
|
|
.. d2:: diagrams/actor_tree.d2
|
|
|
|
|
:alt: a supervision tree of actor processes
|
|
|
|
|
:margin:
|
|
|
|
|
:caption: every arrow is a parent which **must wait** on its kids
|
|
|
|
|
|
|
|
|
|
Your first actor tree
|
|
|
|
|
---------------------
|
|
|
|
|
``trio`` takes the hard-line position that a parent task **must
|
|
|
|
|
wait** on the children it spawns; causality_ is paramount! So
|
|
|
|
|
does ``tractor``, one abstraction layer up:
|
|
|
|
|
``tractor.open_nursery()`` yields an ``ActorNursery`` which
|
|
|
|
|
**must** wait on its spawned *subactors* to complete (or error)
|
|
|
|
|
before the ``async with`` block exits, in the same causal_ way a
|
|
|
|
|
``trio`` nursery waits on its subtasks. That includes any one
|
|
|
|
|
child's crash cancelling all of its siblings: *one-cancels-all*
|
|
|
|
|
supervision, `exactly like trio`_.
|
|
|
|
|
|
|
|
|
|
Enough preamble, spawn a process:
|
|
|
|
|
|
|
|
|
|
.. literalinclude:: ../../examples/actor_spawning_and_causality.py
|
|
|
|
|
:caption: examples/actor_spawning_and_causality.py
|
|
|
|
|
:language: python
|
|
|
|
|
|
|
|
|
|
Run it::
|
|
|
|
|
|
|
|
|
|
$ python examples/actor_spawning_and_causality.py
|
|
|
|
|
Dang that's beautiful
|
|
|
|
|
|
|
|
|
|
What's going on here?
|
|
|
|
|
|
|
|
|
|
- ``trio.run(main)`` starts the **root actor**; the ``tractor``
|
Port docs off `run_in_actor` + `Portal.wait_for_result`
The 8-page docs sweep of the #477 removal, ahead of the API's
excision,
- `start/quickstart.rst`: the first-actor-tree walkthrough now
narrates the (migrated) `to_actor.run()` example — no portal
in hand until the daemon section introduces `start_actor()`.
- `guide/spawning.rst`: the one-shot section becomes
`to_actor.run()` (blocking call, placement opts, "built on the
primitives" note); lifetime/teardown rules update — one-shots
never make it to nursery exit since each is reaped inside its
own call.
- `guide/rpc.rst`: the `wait_for_result()` section (an API that
dies with the reap cluster, incl. the `NoResult` sentinel)
becomes a `to_actor.run()` one-shot section.
- `api/core.rst`: drop `run_in_actor`/`wait_for_result` from the
autodoc member lists, drop the `Portal.result()` deprecation
note, add a "One-shot task actors" `tractor.to_actor.run`
autodoc section.
- `guide/{asyncio,context,cancellation,parallelism}.rst`:
mention swaps to the successor API.
Gate: `make -C docs html` builds clean; `to_actor.run` autodoc
renders in `api/core.html`.
(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 16:31:02 +00:00
|
|
|
runtime boots *implicitly* inside ``tractor.to_actor.run()``
|
Write the big boi docs content tree
Replace the ancient `docs/index.rst` (still teaching
`tractor.run()`, `@stream` + arbiters..) with a full ~32 page tree
teaching ONLY the current api (`.wait_for_result()`, registrar
naming, `@context` + `open_context()` as the core model),
- landing: hero example, feature cards + canon links,
- `start/`: install + a 4-example quickstart on-ramp,
- `explain/`: an "SC across processes" essay distilling the essence
per #157's orig ask + a runtime architecture tour,
- `guide/`: 12 task-focused pages incl the flagship multi-process
debugging walkthrough, `Context` + `MsgStream` deep-dives,
cancellation semantics (self-vs-cross cancel rules), discovery,
infected `asyncio`, typed msging + the #126 testing-tips page,
- `api/`: 10 curated autodoc pages (all targets import-verified vs
the reorg'd subpkg tree),
- `project/`: changelog include, ported dev-tips (drops old
`docs/dev_tips.rst`) + roadmap.
Every code block is a `literalinclude` from `examples/`
- zero duplication, all CI-run - w/ `d2` figs floated
into the RHS margin per the 3-col design. Build is green; the 24
remaining warnings all source from lib docstring rst-isms or legacy
`NEWS.rst` content.
Substantially resolves #157 (refine round pending); chips at #175 +
#126.
Prompt-IO: ai/prompt-io/claude/20260611T175152Z_8526985c_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
2026-06-11 19:17:14 +00:00
|
|
|
whenever it isn't already up. No special entrypoint, no
|
|
|
|
|
framework takeover - it's just a ``trio`` app,
|
|
|
|
|
- inside ``main()`` a *subactor* is spawned via
|
Port docs off `run_in_actor` + `Portal.wait_for_result`
The 8-page docs sweep of the #477 removal, ahead of the API's
excision,
- `start/quickstart.rst`: the first-actor-tree walkthrough now
narrates the (migrated) `to_actor.run()` example — no portal
in hand until the daemon section introduces `start_actor()`.
- `guide/spawning.rst`: the one-shot section becomes
`to_actor.run()` (blocking call, placement opts, "built on the
primitives" note); lifetime/teardown rules update — one-shots
never make it to nursery exit since each is reaped inside its
own call.
- `guide/rpc.rst`: the `wait_for_result()` section (an API that
dies with the reap cluster, incl. the `NoResult` sentinel)
becomes a `to_actor.run()` one-shot section.
- `api/core.rst`: drop `run_in_actor`/`wait_for_result` from the
autodoc member lists, drop the `Portal.result()` deprecation
note, add a "One-shot task actors" `tractor.to_actor.run`
autodoc section.
- `guide/{asyncio,context,cancellation,parallelism}.rst`:
mention swaps to the successor API.
Gate: `make -C docs html` builds clean; `to_actor.run` autodoc
renders in `api/core.html`.
(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 16:31:02 +00:00
|
|
|
``tractor.to_actor.run()`` and told to run exactly one
|
Write the big boi docs content tree
Replace the ancient `docs/index.rst` (still teaching
`tractor.run()`, `@stream` + arbiters..) with a full ~32 page tree
teaching ONLY the current api (`.wait_for_result()`, registrar
naming, `@context` + `open_context()` as the core model),
- landing: hero example, feature cards + canon links,
- `start/`: install + a 4-example quickstart on-ramp,
- `explain/`: an "SC across processes" essay distilling the essence
per #157's orig ask + a runtime architecture tour,
- `guide/`: 12 task-focused pages incl the flagship multi-process
debugging walkthrough, `Context` + `MsgStream` deep-dives,
cancellation semantics (self-vs-cross cancel rules), discovery,
infected `asyncio`, typed msging + the #126 testing-tips page,
- `api/`: 10 curated autodoc pages (all targets import-verified vs
the reorg'd subpkg tree),
- `project/`: changelog include, ported dev-tips (drops old
`docs/dev_tips.rst`) + roadmap.
Every code block is a `literalinclude` from `examples/`
- zero duplication, all CI-run - w/ `d2` figs floated
into the RHS margin per the 3-col design. Build is green; the 24
remaining warnings all source from lib docstring rst-isms or legacy
`NEWS.rst` content.
Substantially resolves #157 (refine round pending); chips at #175 +
#126.
Prompt-IO: ai/prompt-io/claude/20260611T175152Z_8526985c_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
2026-06-11 19:17:14 +00:00
|
|
|
function: ``cellar_door()``,
|
|
|
|
|
- the subactor, *some_linguist*, boots a fresh ``trio.run()`` in
|
|
|
|
|
a **new process** and executes ``cellar_door()`` as its *main
|
|
|
|
|
task* (note the child proving it is *not* the root with
|
|
|
|
|
``tractor.is_root_process()``), then ships the return value
|
|
|
|
|
back over IPC,
|
Port docs off `run_in_actor` + `Portal.wait_for_result`
The 8-page docs sweep of the #477 removal, ahead of the API's
excision,
- `start/quickstart.rst`: the first-actor-tree walkthrough now
narrates the (migrated) `to_actor.run()` example — no portal
in hand until the daemon section introduces `start_actor()`.
- `guide/spawning.rst`: the one-shot section becomes
`to_actor.run()` (blocking call, placement opts, "built on the
primitives" note); lifetime/teardown rules update — one-shots
never make it to nursery exit since each is reaped inside its
own call.
- `guide/rpc.rst`: the `wait_for_result()` section (an API that
dies with the reap cluster, incl. the `NoResult` sentinel)
becomes a `to_actor.run()` one-shot section.
- `api/core.rst`: drop `run_in_actor`/`wait_for_result` from the
autodoc member lists, drop the `Portal.result()` deprecation
note, add a "One-shot task actors" `tractor.to_actor.run`
autodoc section.
- `guide/{asyncio,context,cancellation,parallelism}.rst`:
mention swaps to the successor API.
Gate: `make -C docs html` builds clean; `to_actor.run` autodoc
renders in `api/core.html`.
(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 16:31:02 +00:00
|
|
|
- the call *blocks* until that final result arrives, then
|
|
|
|
|
returns it - causality is preserved: your task only proceeds
|
|
|
|
|
once the child is *done*, dead, and reaped.
|
Write the big boi docs content tree
Replace the ancient `docs/index.rst` (still teaching
`tractor.run()`, `@stream` + arbiters..) with a full ~32 page tree
teaching ONLY the current api (`.wait_for_result()`, registrar
naming, `@context` + `open_context()` as the core model),
- landing: hero example, feature cards + canon links,
- `start/`: install + a 4-example quickstart on-ramp,
- `explain/`: an "SC across processes" essay distilling the essence
per #157's orig ask + a runtime architecture tour,
- `guide/`: 12 task-focused pages incl the flagship multi-process
debugging walkthrough, `Context` + `MsgStream` deep-dives,
cancellation semantics (self-vs-cross cancel rules), discovery,
infected `asyncio`, typed msging + the #126 testing-tips page,
- `api/`: 10 curated autodoc pages (all targets import-verified vs
the reorg'd subpkg tree),
- `project/`: changelog include, ported dev-tips (drops old
`docs/dev_tips.rst`) + roadmap.
Every code block is a `literalinclude` from `examples/`
- zero duplication, all CI-run - w/ `d2` figs floated
into the RHS margin per the 3-col design. Build is green; the 24
remaining warnings all source from lib docstring rst-isms or legacy
`NEWS.rst` content.
Substantially resolves #157 (refine round pending); chips at #175 +
#126.
Prompt-IO: ai/prompt-io/claude/20260611T175152Z_8526985c_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
2026-06-11 19:17:14 +00:00
|
|
|
|
|
|
|
|
.. margin:: Just need a worker pool?
|
|
|
|
|
|
|
|
|
|
If all you want is to throw *sync* functions at your cores,
|
|
|
|
|
also check out trio-parallel_. ``tractor`` is aimed at
|
|
|
|
|
structured, (possibly) distributed *trees* of cooperating
|
|
|
|
|
``trio`` programs; a worker pool is a trivial special case.
|
|
|
|
|
|
|
|
|
|
.. note::
|
|
|
|
|
|
Port docs off `run_in_actor` + `Portal.wait_for_result`
The 8-page docs sweep of the #477 removal, ahead of the API's
excision,
- `start/quickstart.rst`: the first-actor-tree walkthrough now
narrates the (migrated) `to_actor.run()` example — no portal
in hand until the daemon section introduces `start_actor()`.
- `guide/spawning.rst`: the one-shot section becomes
`to_actor.run()` (blocking call, placement opts, "built on the
primitives" note); lifetime/teardown rules update — one-shots
never make it to nursery exit since each is reaped inside its
own call.
- `guide/rpc.rst`: the `wait_for_result()` section (an API that
dies with the reap cluster, incl. the `NoResult` sentinel)
becomes a `to_actor.run()` one-shot section.
- `api/core.rst`: drop `run_in_actor`/`wait_for_result` from the
autodoc member lists, drop the `Portal.result()` deprecation
note, add a "One-shot task actors" `tractor.to_actor.run`
autodoc section.
- `guide/{asyncio,context,cancellation,parallelism}.rst`:
mention swaps to the successor API.
Gate: `make -C docs html` builds clean; `to_actor.run` autodoc
renders in `api/core.html`.
(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 16:31:02 +00:00
|
|
|
``to_actor.run()`` (parlance of ``trio.to_thread`` and
|
|
|
|
|
friends) is the *convenience* wrapper: one-shot
|
Write the big boi docs content tree
Replace the ancient `docs/index.rst` (still teaching
`tractor.run()`, `@stream` + arbiters..) with a full ~32 page tree
teaching ONLY the current api (`.wait_for_result()`, registrar
naming, `@context` + `open_context()` as the core model),
- landing: hero example, feature cards + canon links,
- `start/`: install + a 4-example quickstart on-ramp,
- `explain/`: an "SC across processes" essay distilling the essence
per #157's orig ask + a runtime architecture tour,
- `guide/`: 12 task-focused pages incl the flagship multi-process
debugging walkthrough, `Context` + `MsgStream` deep-dives,
cancellation semantics (self-vs-cross cancel rules), discovery,
infected `asyncio`, typed msging + the #126 testing-tips page,
- `api/`: 10 curated autodoc pages (all targets import-verified vs
the reorg'd subpkg tree),
- `project/`: changelog include, ported dev-tips (drops old
`docs/dev_tips.rst`) + roadmap.
Every code block is a `literalinclude` from `examples/`
- zero duplication, all CI-run - w/ `d2` figs floated
into the RHS margin per the 3-col design. Build is green; the 24
remaining warnings all source from lib docstring rst-isms or legacy
`NEWS.rst` content.
Substantially resolves #157 (refine round pending); chips at #175 +
#126.
Prompt-IO: ai/prompt-io/claude/20260611T175152Z_8526985c_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
2026-06-11 19:17:14 +00:00
|
|
|
spawn-run-reap semantics for when a subactor's entire job is
|
|
|
|
|
a single function call. The core primitives are
|
Port docs off `run_in_actor` + `Portal.wait_for_result`
The 8-page docs sweep of the #477 removal, ahead of the API's
excision,
- `start/quickstart.rst`: the first-actor-tree walkthrough now
narrates the (migrated) `to_actor.run()` example — no portal
in hand until the daemon section introduces `start_actor()`.
- `guide/spawning.rst`: the one-shot section becomes
`to_actor.run()` (blocking call, placement opts, "built on the
primitives" note); lifetime/teardown rules update — one-shots
never make it to nursery exit since each is reaped inside its
own call.
- `guide/rpc.rst`: the `wait_for_result()` section (an API that
dies with the reap cluster, incl. the `NoResult` sentinel)
becomes a `to_actor.run()` one-shot section.
- `api/core.rst`: drop `run_in_actor`/`wait_for_result` from the
autodoc member lists, drop the `Portal.result()` deprecation
note, add a "One-shot task actors" `tractor.to_actor.run`
autodoc section.
- `guide/{asyncio,context,cancellation,parallelism}.rst`:
mention swaps to the successor API.
Gate: `make -C docs html` builds clean; `to_actor.run` autodoc
renders in `api/core.html`.
(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 16:31:02 +00:00
|
|
|
``ActorNursery.start_actor()`` (next up) — which hands you
|
|
|
|
|
a ``Portal``, your handle for invoking tasks in the new
|
|
|
|
|
process's (separate!) memory domain — paired with
|
Write the big boi docs content tree
Replace the ancient `docs/index.rst` (still teaching
`tractor.run()`, `@stream` + arbiters..) with a full ~32 page tree
teaching ONLY the current api (`.wait_for_result()`, registrar
naming, `@context` + `open_context()` as the core model),
- landing: hero example, feature cards + canon links,
- `start/`: install + a 4-example quickstart on-ramp,
- `explain/`: an "SC across processes" essay distilling the essence
per #157's orig ask + a runtime architecture tour,
- `guide/`: 12 task-focused pages incl the flagship multi-process
debugging walkthrough, `Context` + `MsgStream` deep-dives,
cancellation semantics (self-vs-cross cancel rules), discovery,
infected `asyncio`, typed msging + the #126 testing-tips page,
- `api/`: 10 curated autodoc pages (all targets import-verified vs
the reorg'd subpkg tree),
- `project/`: changelog include, ported dev-tips (drops old
`docs/dev_tips.rst`) + roadmap.
Every code block is a `literalinclude` from `examples/`
- zero duplication, all CI-run - w/ `d2` figs floated
into the RHS margin per the 3-col design. Build is green; the 24
remaining warnings all source from lib docstring rst-isms or legacy
`NEWS.rst` content.
Substantially resolves #157 (refine round pending); chips at #175 +
#126.
Prompt-IO: ai/prompt-io/claude/20260611T175152Z_8526985c_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
2026-06-11 19:17:14 +00:00
|
|
|
``Portal.open_context()`` for full, SC-linked cross-actor
|
|
|
|
|
dialogs - see :doc:`/guide/context`.
|
|
|
|
|
|
|
|
|
|
Daemon actors and RPC
|
|
|
|
|
---------------------
|
Port docs off `run_in_actor` + `Portal.wait_for_result`
The 8-page docs sweep of the #477 removal, ahead of the API's
excision,
- `start/quickstart.rst`: the first-actor-tree walkthrough now
narrates the (migrated) `to_actor.run()` example — no portal
in hand until the daemon section introduces `start_actor()`.
- `guide/spawning.rst`: the one-shot section becomes
`to_actor.run()` (blocking call, placement opts, "built on the
primitives" note); lifetime/teardown rules update — one-shots
never make it to nursery exit since each is reaped inside its
own call.
- `guide/rpc.rst`: the `wait_for_result()` section (an API that
dies with the reap cluster, incl. the `NoResult` sentinel)
becomes a `to_actor.run()` one-shot section.
- `api/core.rst`: drop `run_in_actor`/`wait_for_result` from the
autodoc member lists, drop the `Portal.result()` deprecation
note, add a "One-shot task actors" `tractor.to_actor.run`
autodoc section.
- `guide/{asyncio,context,cancellation,parallelism}.rst`:
mention swaps to the successor API.
Gate: `make -C docs html` builds clean; `to_actor.run` autodoc
renders in `api/core.html`.
(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 16:31:02 +00:00
|
|
|
A ``to_actor.run()`` one-shot subactor terminates when its lone
|
|
|
|
|
task returns. But often you want long-lived *daemon* actors
|
|
|
|
|
instead: spawned once, then serving (allowlisted) RPC requests
|
|
|
|
|
until told otherwise. That's ``start_actor()``:
|
Write the big boi docs content tree
Replace the ancient `docs/index.rst` (still teaching
`tractor.run()`, `@stream` + arbiters..) with a full ~32 page tree
teaching ONLY the current api (`.wait_for_result()`, registrar
naming, `@context` + `open_context()` as the core model),
- landing: hero example, feature cards + canon links,
- `start/`: install + a 4-example quickstart on-ramp,
- `explain/`: an "SC across processes" essay distilling the essence
per #157's orig ask + a runtime architecture tour,
- `guide/`: 12 task-focused pages incl the flagship multi-process
debugging walkthrough, `Context` + `MsgStream` deep-dives,
cancellation semantics (self-vs-cross cancel rules), discovery,
infected `asyncio`, typed msging + the #126 testing-tips page,
- `api/`: 10 curated autodoc pages (all targets import-verified vs
the reorg'd subpkg tree),
- `project/`: changelog include, ported dev-tips (drops old
`docs/dev_tips.rst`) + roadmap.
Every code block is a `literalinclude` from `examples/`
- zero duplication, all CI-run - w/ `d2` figs floated
into the RHS margin per the 3-col design. Build is green; the 24
remaining warnings all source from lib docstring rst-isms or legacy
`NEWS.rst` content.
Substantially resolves #157 (refine round pending); chips at #175 +
#126.
Prompt-IO: ai/prompt-io/claude/20260611T175152Z_8526985c_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
2026-06-11 19:17:14 +00:00
|
|
|
|
|
|
|
|
.. literalinclude:: ../../examples/actor_spawning_and_causality_with_daemon.py
|
|
|
|
|
:caption: examples/actor_spawning_and_causality_with_daemon.py
|
|
|
|
|
:language: python
|
|
|
|
|
|
|
|
|
|
Two lifetime rules to internalize:
|
|
|
|
|
|
Port docs off `run_in_actor` + `Portal.wait_for_result`
The 8-page docs sweep of the #477 removal, ahead of the API's
excision,
- `start/quickstart.rst`: the first-actor-tree walkthrough now
narrates the (migrated) `to_actor.run()` example — no portal
in hand until the daemon section introduces `start_actor()`.
- `guide/spawning.rst`: the one-shot section becomes
`to_actor.run()` (blocking call, placement opts, "built on the
primitives" note); lifetime/teardown rules update — one-shots
never make it to nursery exit since each is reaped inside its
own call.
- `guide/rpc.rst`: the `wait_for_result()` section (an API that
dies with the reap cluster, incl. the `NoResult` sentinel)
becomes a `to_actor.run()` one-shot section.
- `api/core.rst`: drop `run_in_actor`/`wait_for_result` from the
autodoc member lists, drop the `Portal.result()` deprecation
note, add a "One-shot task actors" `tractor.to_actor.run`
autodoc section.
- `guide/{asyncio,context,cancellation,parallelism}.rst`:
mention swaps to the successor API.
Gate: `make -C docs html` builds clean; `to_actor.run` autodoc
renders in `api/core.html`.
(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 16:31:02 +00:00
|
|
|
- a ``to_actor.run()`` one-shot actor lives exactly as long as
|
|
|
|
|
its lone task; the call blocks until that function (and thus
|
|
|
|
|
the process) completes,
|
Write the big boi docs content tree
Replace the ancient `docs/index.rst` (still teaching
`tractor.run()`, `@stream` + arbiters..) with a full ~32 page tree
teaching ONLY the current api (`.wait_for_result()`, registrar
naming, `@context` + `open_context()` as the core model),
- landing: hero example, feature cards + canon links,
- `start/`: install + a 4-example quickstart on-ramp,
- `explain/`: an "SC across processes" essay distilling the essence
per #157's orig ask + a runtime architecture tour,
- `guide/`: 12 task-focused pages incl the flagship multi-process
debugging walkthrough, `Context` + `MsgStream` deep-dives,
cancellation semantics (self-vs-cross cancel rules), discovery,
infected `asyncio`, typed msging + the #126 testing-tips page,
- `api/`: 10 curated autodoc pages (all targets import-verified vs
the reorg'd subpkg tree),
- `project/`: changelog include, ported dev-tips (drops old
`docs/dev_tips.rst`) + roadmap.
Every code block is a `literalinclude` from `examples/`
- zero duplication, all CI-run - w/ `d2` figs floated
into the RHS margin per the 3-col design. Build is green; the 24
remaining warnings all source from lib docstring rst-isms or legacy
`NEWS.rst` content.
Substantially resolves #157 (refine round pending); chips at #175 +
#126.
Prompt-IO: ai/prompt-io/claude/20260611T175152Z_8526985c_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
2026-06-11 19:17:14 +00:00
|
|
|
- a ``start_actor()`` actor *lives forever* - an RPC daemon the
|
|
|
|
|
nursery will happily wait on **indefinitely** - until some
|
|
|
|
|
task explicitly cancels it via ``Portal.cancel_actor()`` (as
|
|
|
|
|
above), or its parent nursery is cancelled wholesale.
|
|
|
|
|
|
|
|
|
|
.. tip::
|
|
|
|
|
|
|
|
|
|
Want your *entire program* to just be a long-lived RPC
|
|
|
|
|
daemon? ``tractor.run_daemon()`` is the blocking shorthand:
|
|
|
|
|
it ``trio.run()``\s a root actor which serves requests until
|
|
|
|
|
cancelled.
|
|
|
|
|
|
|
|
|
|
The ``enable_modules=[__name__]`` kwarg is the other thing to
|
|
|
|
|
notice: it lists the module paths the subactor will load and
|
|
|
|
|
*expose* for remote invocation.
|
|
|
|
|
``await portal.run(movie_theatre_question)`` works because this
|
|
|
|
|
very module is in that allowlist (and note we call it twice; the
|
|
|
|
|
daemon happily serves repeat requests). Ask for a function from
|
|
|
|
|
any module *not* enabled and you're denied with a
|
|
|
|
|
``ModuleNotExposed`` error: a simple, capability-style
|
|
|
|
|
restriction mechanism built on Python's own module system.
|
|
|
|
|
|
|
|
|
|
We are *processes*
|
|
|
|
|
------------------
|
|
|
|
|
Why processes (and not, say, threads)? Python has a GIL and an
|
|
|
|
|
`actor model`_ by definition shares **nothing** between its
|
|
|
|
|
concurrent units, so real OS processes are the natural fit: you
|
|
|
|
|
get all your cores locally, and since actors only ever talk via
|
|
|
|
|
IPC, the exact same code distributes over multiple hosts without
|
|
|
|
|
modification.
|
|
|
|
|
|
|
|
|
|
Of course, the moment you hear "process trees" you should be
|
|
|
|
|
asking: *what about zombies?* Watch ``tractor`` eat one for
|
|
|
|
|
breakfast - run this while monitoring your process tree::
|
|
|
|
|
|
|
|
|
|
$TERM -e watch -n 0.1 "pstree -a $$" \
|
|
|
|
|
& python examples/parallelism/we_are_processes.py \
|
|
|
|
|
&& kill $!
|
|
|
|
|
|
|
|
|
|
.. literalinclude:: ../../examples/parallelism/we_are_processes.py
|
|
|
|
|
:caption: examples/parallelism/we_are_processes.py
|
|
|
|
|
:language: python
|
|
|
|
|
|
|
|
|
|
.. margin:: Who's who in ``pstree``?
|
|
|
|
|
|
|
|
|
|
Every subactor (best-effort, via the optional
|
|
|
|
|
``setproctitle`` dep) re-titles its OS process like
|
Fix review nits from PR #460 self-review
Address the actionable findings from the `/code-review` pass
(#1-6); the d2-ext + docstring nits (#7-10) are left for a
follow-up.
Deats,
- `uds_transport_actor_tree.py`: `portal.chan.raddr.sockpath` is
the *shared listener* socket (named for the root registrar), NOT
the child's path — relabel it + lead with the per-child peer pid,
and stop claiming it's the child addr in the docstring,
- `docs.yml`: scope the `pages` `concurrency` group to the `deploy`
job w/ `cancel-in-progress: false` so a PR build can't cancel an
in-flight production deploy,
- `architecture.rst`: `'subint'` is not a selectable `start_method`
on this branch (`SpawnMethodKey` lacks it) — reframe as
in-development/roadmap,
- `context.rst`: `StreamOverrun` isn't re-exported from `tractor`;
point at `tractor._exceptions`,
- `debugging/`: sweep the 3 literalinclude'd examples off the
deprecated `.result()` -> `.wait_for_result()`,
- `quickstart.rst`: proc-title is `name@pid` (per `Aid.reprol`),
not `@uuid`.
NOTE, the `debugging/` examples are pexpect-tested; re-run
`tests/devx/test_debugger.py` for them.
(this patch was generated in some part by [`claude-code`][claude-code-gh])
[claude-code-gh]: https://github.com/anthropics/claude-code
2026-06-25 21:07:44 +00:00
|
|
|
``_subactor[worker_0@<pid>]``, so ``pstree``/``htop``/
|
Write the big boi docs content tree
Replace the ancient `docs/index.rst` (still teaching
`tractor.run()`, `@stream` + arbiters..) with a full ~32 page tree
teaching ONLY the current api (`.wait_for_result()`, registrar
naming, `@context` + `open_context()` as the core model),
- landing: hero example, feature cards + canon links,
- `start/`: install + a 4-example quickstart on-ramp,
- `explain/`: an "SC across processes" essay distilling the essence
per #157's orig ask + a runtime architecture tour,
- `guide/`: 12 task-focused pages incl the flagship multi-process
debugging walkthrough, `Context` + `MsgStream` deep-dives,
cancellation semantics (self-vs-cross cancel rules), discovery,
infected `asyncio`, typed msging + the #126 testing-tips page,
- `api/`: 10 curated autodoc pages (all targets import-verified vs
the reorg'd subpkg tree),
- `project/`: changelog include, ported dev-tips (drops old
`docs/dev_tips.rst`) + roadmap.
Every code block is a `literalinclude` from `examples/`
- zero duplication, all CI-run - w/ `d2` figs floated
into the RHS margin per the 3-col design. Build is green; the 24
remaining warnings all source from lib docstring rst-isms or legacy
`NEWS.rst` content.
Substantially resolves #157 (refine round pending); chips at #175 +
#126.
Prompt-IO: ai/prompt-io/claude/20260611T175152Z_8526985c_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
2026-06-11 19:17:14 +00:00
|
|
|
``pgrep -f`` can tell your actors apart at a glance.
|
|
|
|
|
|
2026-06-28 02:14:34 +00:00
|
|
|
You'll see something like (one subactor per core - 24 on this box,
|
|
|
|
|
trimmed here)::
|
Write the big boi docs content tree
Replace the ancient `docs/index.rst` (still teaching
`tractor.run()`, `@stream` + arbiters..) with a full ~32 page tree
teaching ONLY the current api (`.wait_for_result()`, registrar
naming, `@context` + `open_context()` as the core model),
- landing: hero example, feature cards + canon links,
- `start/`: install + a 4-example quickstart on-ramp,
- `explain/`: an "SC across processes" essay distilling the essence
per #157's orig ask + a runtime architecture tour,
- `guide/`: 12 task-focused pages incl the flagship multi-process
debugging walkthrough, `Context` + `MsgStream` deep-dives,
cancellation semantics (self-vs-cross cancel rules), discovery,
infected `asyncio`, typed msging + the #126 testing-tips page,
- `api/`: 10 curated autodoc pages (all targets import-verified vs
the reorg'd subpkg tree),
- `project/`: changelog include, ported dev-tips (drops old
`docs/dev_tips.rst`) + roadmap.
Every code block is a `literalinclude` from `examples/`
- zero duplication, all CI-run - w/ `d2` figs floated
into the RHS margin per the 3-col design. Build is green; the 24
remaining warnings all source from lib docstring rst-isms or legacy
`NEWS.rst` content.
Substantially resolves #157 (refine round pending); chips at #175 +
#126.
Prompt-IO: ai/prompt-io/claude/20260611T175152Z_8526985c_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
2026-06-11 19:17:14 +00:00
|
|
|
|
|
|
|
|
$ python examples/parallelism/we_are_processes.py
|
2026-06-28 02:14:34 +00:00
|
|
|
This tree will self-destruct in 2s..
|
|
|
|
|
|
|
|
|
|
Started ep-task in subactor,
|
|
|
|
|
0::'worker_0'@218140
|
|
|
|
|
|
|
|
|
|
Started ep-task in subactor,
|
|
|
|
|
2::'worker_2'@218134
|
Write the big boi docs content tree
Replace the ancient `docs/index.rst` (still teaching
`tractor.run()`, `@stream` + arbiters..) with a full ~32 page tree
teaching ONLY the current api (`.wait_for_result()`, registrar
naming, `@context` + `open_context()` as the core model),
- landing: hero example, feature cards + canon links,
- `start/`: install + a 4-example quickstart on-ramp,
- `explain/`: an "SC across processes" essay distilling the essence
per #157's orig ask + a runtime architecture tour,
- `guide/`: 12 task-focused pages incl the flagship multi-process
debugging walkthrough, `Context` + `MsgStream` deep-dives,
cancellation semantics (self-vs-cross cancel rules), discovery,
infected `asyncio`, typed msging + the #126 testing-tips page,
- `api/`: 10 curated autodoc pages (all targets import-verified vs
the reorg'd subpkg tree),
- `project/`: changelog include, ported dev-tips (drops old
`docs/dev_tips.rst`) + roadmap.
Every code block is a `literalinclude` from `examples/`
- zero duplication, all CI-run - w/ `d2` figs floated
into the RHS margin per the 3-col design. Build is green; the 24
remaining warnings all source from lib docstring rst-isms or legacy
`NEWS.rst` content.
Substantially resolves #157 (refine round pending); chips at #175 +
#126.
Prompt-IO: ai/prompt-io/claude/20260611T175152Z_8526985c_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
2026-06-11 19:17:14 +00:00
|
|
|
|
2026-06-28 02:14:34 +00:00
|
|
|
Started ep-task in subactor,
|
|
|
|
|
1::'worker_1'@218137
|
|
|
|
|
|
|
|
|
|
Started ep-task in subactor,
|
|
|
|
|
3::'worker_3'@218132
|
|
|
|
|
|
|
|
|
|
Zombies Contained
|
Write the big boi docs content tree
Replace the ancient `docs/index.rst` (still teaching
`tractor.run()`, `@stream` + arbiters..) with a full ~32 page tree
teaching ONLY the current api (`.wait_for_result()`, registrar
naming, `@context` + `open_context()` as the core model),
- landing: hero example, feature cards + canon links,
- `start/`: install + a 4-example quickstart on-ramp,
- `explain/`: an "SC across processes" essay distilling the essence
per #157's orig ask + a runtime architecture tour,
- `guide/`: 12 task-focused pages incl the flagship multi-process
debugging walkthrough, `Context` + `MsgStream` deep-dives,
cancellation semantics (self-vs-cross cancel rules), discovery,
infected `asyncio`, typed msging + the #126 testing-tips page,
- `api/`: 10 curated autodoc pages (all targets import-verified vs
the reorg'd subpkg tree),
- `project/`: changelog include, ported dev-tips (drops old
`docs/dev_tips.rst`) + roadmap.
Every code block is a `literalinclude` from `examples/`
- zero duplication, all CI-run - w/ `d2` figs floated
into the RHS margin per the 3-col design. Build is green; the 24
remaining warnings all source from lib docstring rst-isms or legacy
`NEWS.rst` content.
Substantially resolves #157 (refine round pending); chips at #175 +
#126.
Prompt-IO: ai/prompt-io/claude/20260611T175152Z_8526985c_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
2026-06-11 19:17:14 +00:00
|
|
|
|
2026-06-28 02:14:34 +00:00
|
|
|
(The ``Started ep-task`` lines land in whatever order the OS
|
|
|
|
|
schedules them; they're separate *processes*, racing, and that's
|
|
|
|
|
the point.)
|
|
|
|
|
|
|
|
|
|
One subactor is spawned per core - concurrently, from background
|
|
|
|
|
``trio`` tasks, so each child's cold ``import tractor`` overlaps
|
|
|
|
|
instead of stacking. Each runs a ``@tractor.context``
|
|
|
|
|
``endpoint()`` that ``ctx.started()``-hands its name and pid back
|
|
|
|
|
through ``Portal.open_context()`` (those ``Started ep-task``
|
|
|
|
|
lines), then parks in ``trio.sleep_forever()``. Then the root
|
|
|
|
|
*crashes on purpose* and the ``ActorNursery`` responds with hard
|
|
|
|
|
``trio`` discipline: every child is cancelled, every process is
|
|
|
|
|
reaped, the error propagates to ``trio.run()``, and your terminal
|
|
|
|
|
prints ``Zombies Contained``. No orphans, no ``kill -9``
|
|
|
|
|
archaeology in ``htop`` afterwards.
|
Write the big boi docs content tree
Replace the ancient `docs/index.rst` (still teaching
`tractor.run()`, `@stream` + arbiters..) with a full ~32 page tree
teaching ONLY the current api (`.wait_for_result()`, registrar
naming, `@context` + `open_context()` as the core model),
- landing: hero example, feature cards + canon links,
- `start/`: install + a 4-example quickstart on-ramp,
- `explain/`: an "SC across processes" essay distilling the essence
per #157's orig ask + a runtime architecture tour,
- `guide/`: 12 task-focused pages incl the flagship multi-process
debugging walkthrough, `Context` + `MsgStream` deep-dives,
cancellation semantics (self-vs-cross cancel rules), discovery,
infected `asyncio`, typed msging + the #126 testing-tips page,
- `api/`: 10 curated autodoc pages (all targets import-verified vs
the reorg'd subpkg tree),
- `project/`: changelog include, ported dev-tips (drops old
`docs/dev_tips.rst`) + roadmap.
Every code block is a `literalinclude` from `examples/`
- zero duplication, all CI-run - w/ `d2` figs floated
into the RHS margin per the 3-col design. Build is green; the 24
remaining warnings all source from lib docstring rst-isms or legacy
`NEWS.rst` content.
Substantially resolves #157 (refine round pending); chips at #175 +
#126.
Prompt-IO: ai/prompt-io/claude/20260611T175152Z_8526985c_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
2026-06-11 19:17:14 +00:00
|
|
|
|
|
|
|
|
.. note::
|
|
|
|
|
|
|
|
|
|
**The zombie-safety guarantee**: ``tractor`` tries to protect
|
|
|
|
|
you from zombies, *no matter what*. If you can create zombie
|
|
|
|
|
child processes (without using a system signal) it **is a
|
|
|
|
|
bug** - please report it so we can hunt it down.
|
|
|
|
|
|
|
|
|
|
A trynamic first scene
|
|
|
|
|
----------------------
|
|
|
|
|
So far the root actor has done all the talking, but subactors
|
|
|
|
|
can just as well discover and call *each other*. Let's direct a
|
|
|
|
|
couple actors and have them run their lines for the hip new film
|
|
|
|
|
we're shooting:
|
|
|
|
|
|
|
|
|
|
.. literalinclude:: ../../examples/a_trynamic_first_scene.py
|
|
|
|
|
:caption: examples/a_trynamic_first_scene.py
|
|
|
|
|
:language: python
|
|
|
|
|
|
|
|
|
|
The script of the scene (runtime ``INFO`` log lines trimmed)::
|
|
|
|
|
|
|
|
|
|
$ python examples/a_trynamic_first_scene.py
|
|
|
|
|
Alright... Action!
|
|
|
|
|
Hi my name is gretchen
|
|
|
|
|
Hi my name is donny
|
|
|
|
|
CUTTTT CUUTT CUT!!! Donny!! You're supposed to say...
|
|
|
|
|
|
|
|
|
|
The new tricks in play:
|
|
|
|
|
|
|
|
|
|
- two subactors, *donny* and *gretchen*, are each told to run
|
|
|
|
|
``say_hello()`` targeting the *other* by name,
|
|
|
|
|
- ``tractor.wait_for_actor()`` blocks until the named peer has
|
|
|
|
|
registered with the tree's *registrar* (every actor announces
|
|
|
|
|
itself at boot), then yields a ``Portal`` connected
|
|
|
|
|
**directly** to that peer,
|
|
|
|
|
- each actor invokes its partner's ``hi()`` over that portal:
|
|
|
|
|
actor-to-actor RPC with the root merely *directing* - and both
|
|
|
|
|
final lines flow back to ``main()`` via
|
|
|
|
|
``await portal.wait_for_result()``,
|
|
|
|
|
- ``tractor.log.get_console_log("INFO")`` cranks up runtime
|
|
|
|
|
logging so you can watch the spawn/register/cancel machinery
|
|
|
|
|
narrate itself; remove it for a quiet set.
|
|
|
|
|
|
|
|
|
|
Cross-actor calls look just like (async) function calls; there
|
|
|
|
|
are no proxy objects and no shared references, only messages B)
|
|
|
|
|
|
|
|
|
|
Crash handling, native feeling
|
|
|
|
|
------------------------------
|
|
|
|
|
One last teaser before the guide proper. Flip exactly one
|
|
|
|
|
switch:
|
|
|
|
|
|
|
|
|
|
.. code:: python
|
|
|
|
|
|
|
|
|
|
async with tractor.open_nursery(
|
|
|
|
|
debug_mode=True,
|
|
|
|
|
) as an:
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
and any crash, in *any* actor at *any* depth of the tree, drops
|
|
|
|
|
your terminal into a multi-process-safe pdbp_ REPL at the
|
|
|
|
|
offending frame, with the rest of the tree held back from
|
|
|
|
|
clobbering the tty. ``await tractor.pause()`` likewise gives you
|
|
|
|
|
a breakpoint that *just works* inside subprocesses. We think it
|
|
|
|
|
might be the first native multi-process debugging UX for Python;
|
|
|
|
|
get the full tour in :doc:`/guide/debugging`.
|
|
|
|
|
|
|
|
|
|
Where to next?
|
|
|
|
|
--------------
|
|
|
|
|
You can now boot a runtime, spawn one-shot and daemon actors,
|
|
|
|
|
make cross-process RPC calls, and contain zombies: that's the
|
|
|
|
|
on-ramp done. The guide takes each subsystem deeper,
|
|
|
|
|
|
|
|
|
|
- :doc:`/explain/sc-distributed` - the structured concurrency
|
|
|
|
|
worldview and how ``tractor`` extends it across processes,
|
|
|
|
|
- :doc:`/guide/spawning` - everything ``ActorNursery``: spawn
|
|
|
|
|
kwargs, lifetimes and supervision semantics,
|
|
|
|
|
- :doc:`/guide/rpc` - the ``Portal`` in depth: calling into
|
|
|
|
|
another actor's memory domain,
|
|
|
|
|
- :doc:`/guide/context` - the core API: ``@tractor.context``
|
|
|
|
|
endpoints, the ``ctx.started()`` handshake, and SC-linked
|
|
|
|
|
cross-actor task pairs,
|
|
|
|
|
- :doc:`/guide/streaming` - bidirectional ``MsgStream`` dialogs
|
|
|
|
|
and fan-out broadcasting,
|
|
|
|
|
- :doc:`/guide/debugging` - the multi-process REPL, crash
|
|
|
|
|
handling mode, and ``tractor.pause()``,
|
|
|
|
|
- :doc:`/guide/asyncio` - "infected ``asyncio``" mode: SC
|
|
|
|
|
supervision wrapped around ``asyncio`` tasks,
|
|
|
|
|
- :doc:`/guide/discovery` - registries, service daemons, and
|
|
|
|
|
finding actors from anywhere in (or out of) the tree.
|
|
|
|
|
|
|
|
|
|
.. _structured concurrency: https://en.wikipedia.org/wiki/Structured_concurrency
|
|
|
|
|
.. _nursery: https://trio.readthedocs.io/en/latest/reference-core.html#nurseries-and-spawning
|
|
|
|
|
.. _causality: https://vorpus.org/blog/some-thoughts-on-asynchronous-api-design-in-a-post-asyncawait-world/#c-c-c-c-causality-breaker
|
|
|
|
|
.. _causal: https://vorpus.org/blog/some-thoughts-on-asynchronous-api-design-in-a-post-asyncawait-world/#causality
|
|
|
|
|
.. _exactly like trio: https://trio.readthedocs.io/en/latest/reference-core.html#cancellation-semantics
|
|
|
|
|
.. _actor model: https://en.wikipedia.org/wiki/Actor_model
|
|
|
|
|
.. _trio-parallel: https://github.com/richardsheridan/trio-parallel
|
|
|
|
|
.. _pdbp: https://github.com/mdmintz/pdbp
|