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
|
|
|
Higher-level cluster APIs
|
|
|
|
|
=========================
|
|
|
|
|
|
|
|
|
|
Sometimes you don't want a hand-crafted supervision tree; you want
|
|
|
|
|
"a pile of workers, one per core, now please". For that there's
|
|
|
|
|
:func:`tractor.open_actor_cluster`: a convenience wrapper which
|
|
|
|
|
spawns a *flat* cluster of subactors and hands you back a portal to
|
|
|
|
|
each,
|
|
|
|
|
|
|
|
|
|
.. code:: python
|
|
|
|
|
|
|
|
|
|
@acm
|
|
|
|
|
async def open_actor_cluster(
|
|
|
|
|
modules: list[str], # RPC allowlist for workers
|
|
|
|
|
count: int = cpu_count(), # one per core by default
|
|
|
|
|
names: list[str]|None = None, # default: 'worker_{i}'
|
|
|
|
|
hard_kill: bool = False, # fwd to `an.cancel()`
|
|
|
|
|
**runtime_kwargs, # fwd to `open_root_actor()`
|
|
|
|
|
) -> AsyncGenerator[dict[str, tractor.Portal], None]:
|
|
|
|
|
|
|
|
|
|
A cluster in one block
|
|
|
|
|
----------------------
|
|
|
|
|
|
|
|
|
|
.. literalinclude:: ../../examples/quick_cluster.py
|
|
|
|
|
:caption: examples/quick_cluster.py
|
|
|
|
|
:language: python
|
|
|
|
|
|
|
|
|
|
Walkthrough,
|
|
|
|
|
|
|
|
|
|
- ``open_actor_cluster(modules=[__name__])`` concurrently spawns
|
|
|
|
|
one subactor per detected core (per
|
|
|
|
|
:func:`multiprocessing.cpu_count`); the ``modules`` list is the
|
|
|
|
|
usual ``enable_modules``-style capability allowlist so workers
|
|
|
|
|
may run functions defined in this module,
|
|
|
|
|
- it yields a ``dict[str, tractor.Portal]`` mapping worker name to
|
|
|
|
|
portal; note the keys get prefixed with the *spawning* actor's
|
|
|
|
|
name, so from the root you'll see ``'root.worker_0'``,
|
|
|
|
|
``'root.worker_1'``, etc.,
|
|
|
|
|
- a plain :class:`trio.Nursery` then fans out one
|
|
|
|
|
``portal.run(sleepy_jane)`` per worker; each prints its actor
|
|
|
|
|
``.uid`` from inside its own process then naps forever — what
|
|
|
|
|
runs *inside* each worker (and how many tasks you point at it)
|
|
|
|
|
is entirely yours to compose,
|
|
|
|
|
- ``tractor.trionics.collapse_eg()`` un-nests the strict
|
|
|
|
|
``ExceptionGroup`` wrapping so the demo's ``KeyboardInterrupt``
|
|
|
|
|
surfaces as itself instead of arriving eg-boxed,
|
|
|
|
|
- on block exit the whole fleet is torn down for you via
|
|
|
|
|
:meth:`tractor.ActorNursery.cancel`; pass ``hard_kill=True`` at
|
|
|
|
|
open time to skip straight to OS-level termination instead of
|
|
|
|
|
the graceful ladder described in :doc:`/guide/cancellation`.
|
|
|
|
|
|
|
|
|
|
Sizing, naming, fleet-wide options
|
|
|
|
|
----------------------------------
|
|
|
|
|
|
|
|
|
|
``count`` doesn't have to be core-count and the auto-generated
|
|
|
|
|
``'worker_{i}'`` names are just the default; pass your own (the
|
|
|
|
|
length must match ``count`` or you get a ``ValueError``). Any
|
|
|
|
|
extra ``**runtime_kwargs`` pass through verbatim to
|
|
|
|
|
:func:`tractor.open_root_actor`, so fleet-wide runtime options are
|
|
|
|
|
one kwarg away,
|
|
|
|
|
|
|
|
|
|
.. code:: python
|
|
|
|
|
|
|
|
|
|
async with tractor.open_actor_cluster(
|
2026-08-20 21:21:03 +00:00
|
|
|
modules=[
|
|
|
|
|
'mylib.workers',
|
|
|
|
|
tractor.to_actor.MODULE,
|
|
|
|
|
],
|
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
|
|
|
count=4,
|
|
|
|
|
names=['scout', 'miner', 'smelter', 'smith'],
|
|
|
|
|
debug_mode=True, # whole-fleet crash-to-REPL
|
|
|
|
|
) as portal_map:
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
From here the composition patterns are the usual ``tractor`` fare:
|
2026-08-20 03:29:02 +00:00
|
|
|
``portal.run()`` for bare one-shot RPCs (as in the demo),
|
2026-08-20 21:21:03 +00:00
|
|
|
``tractor.to_actor.run(..., portal=portal)`` for cancellation-linked
|
|
|
|
|
one-shot tasks in an existing worker (include
|
|
|
|
|
``tractor.to_actor.MODULE`` in ``modules``; the cluster still owns
|
|
|
|
|
the worker's lifetime), or — for a persistent bidirectional dialog
|
|
|
|
|
per worker — concurrently enter N ``portal.open_context()`` blocks 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
|
|
|
``tractor.trionics.gather_contexts()``; see :doc:`/guide/context`
|
|
|
|
|
for that whole layer.
|
|
|
|
|
|
|
|
|
|
Clusters vs. nurseries
|
|
|
|
|
----------------------
|
|
|
|
|
|
|
|
|
|
.. d2:: diagrams/actor_tree.d2
|
|
|
|
|
:margin:
|
|
|
|
|
:caption: The general shape: arbitrary nesting. A cluster is
|
|
|
|
|
this, minus the nesting.
|
|
|
|
|
:alt: a nested supervision tree of subactors
|
|
|
|
|
|
|
|
|
|
``open_actor_cluster()`` is sugar, not a new primitive: under the
|
|
|
|
|
hood it's just :func:`tractor.open_nursery` plus N concurrent
|
2026-08-20 03:29:02 +00:00
|
|
|
:meth:`~tractor.ActorNursery.start_actor` calls plus a ``.cancel()``
|
|
|
|
|
on the way out. Reach for it when,
|
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
|
|
|
|
|
|
|
|
- you want a *flat*, homogeneous fleet (classic worker-pool or
|
|
|
|
|
map-style fan-out shapes),
|
|
|
|
|
- "one per core" — or a fixed ``count`` — is the right sizing
|
|
|
|
|
story,
|
|
|
|
|
- every child can share the same spawn options.
|
|
|
|
|
|
|
|
|
|
Drop down to a raw :class:`tractor.ActorNursery` when the topology
|
|
|
|
|
gets any fancier: nested trees, heterogeneous children, per-child
|
|
|
|
|
``debug_mode``/transport/module options, daemons mixed with
|
|
|
|
|
one-shot workers, and so on (see :doc:`/guide/parallelism` for a
|
|
|
|
|
hand-rolled pool). Either way the supervision semantics are
|
|
|
|
|
identical: one-cancels-all error propagation and the no-zombies
|
|
|
|
|
guarantee from :doc:`/guide/cancellation` apply to clusters too.
|
|
|
|
|
|
|
|
|
|
Provisional, by design
|
|
|
|
|
----------------------
|
|
|
|
|
|
|
|
|
|
.. note::
|
|
|
|
|
|
|
|
|
|
APIs in this section are considered **provisional**: the
|
|
|
|
|
signature and semantics of :func:`tractor.open_actor_cluster`
|
|
|
|
|
may shift as higher-level supervision machinery lands. We
|
|
|
|
|
encourage you to try it and provide feedback — the
|
|
|
|
|
`matrix channel`_ is the place to say hi, and `#22`_ tracks the
|
|
|
|
|
broader supervisor-strategy roadmap.
|
|
|
|
|
|
|
|
|
|
.. seealso::
|
|
|
|
|
|
|
|
|
|
- :doc:`/guide/parallelism` — worker pools built "by hand" with
|
|
|
|
|
plain actor nurseries (and why that's easy peasy),
|
|
|
|
|
- :doc:`/guide/cancellation` — the teardown machinery a cluster
|
|
|
|
|
inherits for free.
|
|
|
|
|
|
|
|
|
|
.. _matrix channel: https://matrix.to/#/!tractor:matrix.org
|
|
|
|
|
.. _#22: https://github.com/goodboy/tractor/issues/22
|