Skip to content

post-#472 docs follow ups - #512

Merged
goodboy merged 12 commits into
mainfrom
wkt/big_boi_docs_472_follow_ups
Aug 30, 2026
Merged

post-#472 docs follow ups#512
goodboy merged 12 commits into
mainfrom
wkt/big_boi_docs_472_follow_ups

Conversation

@goodboy

@goodboy goodboy commented Aug 28, 2026

Copy link
Copy Markdown
Owner

Refine typed messaging and discovery examples

Motivation

PR #460 established the modern docs scaffold, while #472 retained the
content work needed to make its guides and examples accurately teach
current APIs. Typed messaging and discovery still needed deeper
coverage, and many docs-visible examples lacked consistent typing and
source style.

This pass documents the runtime's actual payload-validation and
discovery contracts, adds a real dedicated-registrar topology, and
makes the examples easier to read without changing their intentional
failure and debugging behavior.

Summary of changes

  • Expand the typed-messaging guide around pld_spec, sender- versus
    receiver-side validation, custom codecs, and the current boundaries
    of per-task and per-dialog hooks.

  • Add a standalone dedicated-registrar example under
    examples/discovery/. It uses an ephemeral address, bounded
    collision retries, atomic readiness publication, external sibling
    discovery, and validated cross-platform teardown.

  • Apply the repository's typing, docstring, string, and 69-column
    conventions across 38 changed examples while preserving intentional
    debugger failures, cancellation races, and Trio reproducers.

Future follow up

Links

(this pr content was generated in some part by opencode using
gpt-5.6-sol (openai))

The "Toward capability-based msging" section only pointed at the
`#196`/`#36` epics. Fold in the concrete recent state,

- `#365` as the most recent step: driving the whole `pld_spec` off
  plain type-annotations (e.g. annotating a context's
  `open_stream()` with `msgspec.Struct` subtypes) rather than
  explicit `pld_spec=` kwargs.
- clarify that the decorator-level `@tractor.context(pld_spec=...)`
  is already the higher-level path (vs the lower-level
  `tractor.msg._ops.limit_plds()` escape hatch), pointing at
  `tests/msg/test_pldrx_limiting.py` + `test_ext_types_msgspec.py`
  which exercise both.
- `#376` (from @guilledk, `auto_codecs` branch) as the drafted
  public factory API for the `enc_hook`/`dec_hook` pair (today only
  reachable via `tractor.msg._ops`).

Addresses the caps-based-msging bullet in #472.

(this patch was generated in some part by [`claude-code`][claude-code-gh])
[claude-code-gh]: https://github.com/anthropics/claude-code
Add a runnable `examples/dedicated_registrar.py` + a "A dedicated
registrar" subsection in `guide/discovery.rst` demoing the
registrar decoupled from any app tree's root: boot a bare
`tractor.run_daemon([], registry_addrs=[...])` as its own process
(a root actor that does nothing but hold the registry), point the
app tree at the same `registry_addrs`, and discover a service
*through* that external registrar.

This is the buildable-today form of the #472
"Registrar-as-subsystem (not the root actor)" bullet. Two
constraints are called out inline as follow-ups:
`enable_transports` is single-proto per runtime (no multi-backend
registrar yet), and a registrar can only be a root (no `actor_cls`
hook on `start_actor()` to spawn one as a subactor).

(this patch was generated in some part by [`claude-code`][claude-code-gh])
[claude-code-gh]: https://github.com/anthropics/claude-code
Sweep the `examples/debugging/` set for basic typing: add `-> None`
to all 16 bare `async def main()`s and annotate the clean
single-line `open_nursery()` bindings as `tractor.ActorNursery`.

Kept to the unambiguous, runtime-safe cases (these breakpoint/crash
demos can't be run headless); the heterogeneous
multi-line/paren-group nursery bindings + `current_actor()` returns
are left for a later pass. Continues the examples-typing bullet in

(this patch was generated in some part by [`claude-code`][claude-code-gh])
[claude-code-gh]: https://github.com/anthropics/claude-code
Type the runtime objects (`ActorNursery`, `Portal`, `Context`,
`trio.Nursery`) + fn signatures across the 16 highest-visibility,
`literalinclude`-d `examples/` scripts, matching the front-page
`we_are_processes.py` style — so the rendered guides show typed
usage throughout, not just on the landing snippet.

Spans the 3 quickstart-backing scripts + `single_func`,
`remote_error_propagation`, `multiple_streams_one_portal`,
`quick_cluster`, `service_discovery`, `service_daemon_discovery`,
`asynchronous_generators`, `nested_actor_tree`,
`concurrent_actors_primes`, `streaming_broadcast_fanout`,
`rpc_bidir_streaming`, `infected_asyncio_echo_server`,
`typed_payloads`.

Annotation-only (no renames/logic changes); each runs green and the
docs build stays warning-free. Part of the examples-typing bullet
in #472.

(this patch was generated in some part by [`claude-code`][claude-code-gh])
[claude-code-gh]: https://github.com/anthropics/claude-code
Finish the examples-typing sweep with the last non-docs-visible
scripts: `-> None` on the two `trio/` behavior-demo mains (plus a
`trio.TaskStatus` on `hold_lock_forever`) and nursery/portal typing
on `integration/mpi4py/inherit_parent_main.py`.

Leaves `concurrent_futures_primes` (a verbatim stdlib baseline) and
`integration/open_context_and_sleep` (its tractor nursery is
commented out) as-is, and the paren-group `trio.open_nursery()`
bindings unannotated (no clean spot for a preceding annotation).
Completes the examples-typing bullet in #472.

(this patch was generated in some part by [`claude-code`][claude-code-gh])
[claude-code-gh]: https://github.com/anthropics/claude-code
Copilot AI lite review requested due to automatic review settings August 28, 2026 18:54
@goodboy goodboy added the docs label Aug 28, 2026
Comment thread examples/dedicated_registrar.py Outdated
Comment thread examples/dedicated_registrar.py Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new examples/dedicated_registrar.py uses a fixed port and has incomplete subprocess cleanup, which can make the examples-as-tests run flaky and potentially leak a background registrar process.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR updates the documentation and example scripts as follow-ups to the #472 work, primarily by tightening type annotations across examples and extending the discovery guide with a dedicated-registrar pattern example.

Changes:

  • Add/expand type annotations across many examples/ scripts to make the docs/examples more type-explicit.
  • Add a new examples/dedicated_registrar.py and document the “dedicated registrar” pattern in docs/guide/discovery.rst.
  • Expand messaging guide discussion around typed payload contracts and codec hooks, with additional issue/PR references.
File summaries
File Description
examples/uds_transport_actor_tree.py Add explicit ActorNursery/Portal annotations in UDS transport example.
examples/typed_payloads.py Add explicit ActorNursery/Portal annotations in typed payloads example.
examples/trio/send_chan_aclose_masks_beg.py Add explicit return type to main() signature.
examples/trio/lockacquire_not_unmasked.py Add TaskStatus typing and return annotations for async entry points.
examples/streaming_broadcast_fanout.py Add ActorNursery/Portal/Nursery annotations in broadcast fanout example.
examples/service_discovery.py Add typed main() signature and typed portal variables for discovery calls.
examples/service_daemon_discovery.py Add ActorNursery/Portal/Nursery annotations in daemon discovery example.
examples/rpc_bidir_streaming.py Add explicit Portal type annotation for spawned RPC server portal.
examples/remote_error_propagation.py Add return annotations and typed real_actors list.
examples/quick_cluster.py Add return annotation for main() and annotate nursery variable.
examples/parallelism/single_func.py Add return annotations and type pid from to_actor.run.
examples/parallelism/concurrent_actors_primes.py Add argument/variable typing throughout primes worker-pool example.
examples/nested_actor_tree.py Add ActorNursery/Nursery/Portal annotations in nested-tree example.
examples/multiple_streams_one_portal.py Add typing to function params/locals and reformat start_actor call.
examples/integration/mpi4py/inherit_parent_main.py Add ActorNursery/Portal/result annotations in mpi4py integration example.
examples/infected_asyncio_echo_server.py Add return annotations and typed Portal in asyncio infection example.
examples/full_fledged_streaming_service.py Add/extend type annotations in streaming service example.
examples/dedicated_registrar.py New example demonstrating a dedicated external registrar process and discovery through it.
examples/debugging/subactor_error.py Add return annotation for main() in debugging example.
examples/debugging/subactor_breakpoint.py Add return annotation for main() in debugging example.
examples/debugging/subactor_bp_in_ctx.py Add return annotation for main() in debugging example.
examples/debugging/shielded_pause.py Add return annotation for main() in debugging example.
examples/debugging/root_timeout_while_child_crashed.py Add return annotation for main() in debugging example.
examples/debugging/root_self_cancelled_w_error.py Add return annotation for main() in debugging example.
examples/debugging/root_cancelled_but_child_is_in_tty_lock.py Add return annotation for main() in debugging example.
examples/debugging/root_actor_error.py Add return annotation for main() in debugging example.
examples/debugging/root_actor_breakpoint.py Add return annotation for main() in debugging example.
examples/debugging/pm_in_subactor.py Add return annotation for main() in debugging example.
examples/debugging/per_actor_debug.py Add return annotation for main() in debugging example.
examples/debugging/multi_subactors.py Add return annotation for main() in debugging example.
examples/debugging/multi_subactor_root_errors.py Add return annotation for main() in debugging example.
examples/debugging/multi_nested_subactors_error_up_through_nurseries.py Add return annotation for main() in debugging example.
examples/debugging/multi_daemon_subactors.py Add return annotation for main() in debugging example.
examples/debugging/fast_error_in_root_after_spawn.py Add return annotation for main() in debugging example.
examples/asynchronous_generators.py Add return annotation and type key locals in async generator example.
examples/actor_spawning_and_causality.py Add return annotations for example functions.
examples/actor_spawning_and_causality_with_daemon.py Add return annotations and type the spawned portal.
examples/a_trynamic_first_scene.py Add return annotations and type the portal in discovery call.
docs/guide/msging.rst Expand typed messaging roadmap/details and add references (#365, #376).
docs/guide/discovery.rst Document the dedicated registrar pattern and include the new example.
Review details

Suppressed comments (1)

examples/dedicated_registrar.py:118

  • The registrar subprocess cleanup suppresses TimeoutExpired but does not kill the process on timeout, which can leak a background daemon and cause later example runs to fail. Also, send_signal() can raise if the process already exited; it’s safer to suppress that and force-kill on timeout.
        # graceful SIGINT teardown of the standalone registrar.
        registrar.send_signal(signal.SIGINT)
        with suppress(subprocess.TimeoutExpired):
            registrar.wait(timeout=10)
        print('dedicated registrar shut down')
  • Files reviewed: 40/40 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread examples/dedicated_registrar.py Outdated
Comment thread examples/service_discovery.py Outdated
Finish the Python style, typing and docstring pass across the
ordinary, parallelism, Trio and integration examples.

Preserve each demo's runtime behavior while tightening callable,
portal, stream and nursery annotations. Use the modern `.chan`
portal attr and current actor-lifecycle terminology.

(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))
Finish the Python style, typing and docstring pass across the
debugger examples without changing their intentional breakpoints,
failures, cancellation races or timeout reproducers.

Restore full child command lines in the documented process trees
and keep the examples within the 69-column source limit.

(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))
Run the registrar in its own process and prove that a sibling client
discovers the service through registry lookup instead of an existing
peer channel.

Retry ephemeral bind collisions, publish readiness atomically and
validate bounded cross-platform shutdown. Document actual duplicate
name and multi-registrar ordering semantics alongside the example.

Move the demo under the discovery examples and wrap process ownership
in an `@acm`. Record the future public subsystem, Piker service and
pytest isolation follow-ups.

(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))
Document `Started` as the eager sender-side payload check and
`Yield` plus `Return` as receiver-side decoding boundaries without
promising a symmetric error relay.

Separate the working task-scoped codec encoder from the private
per-dialog decoder and the incomplete `@context` hook params.

Link the planned typed `Start` contract and sender-side argument
validation follow-up in #514.

(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))
Capture the human direction, generated changes, review findings and
validation results for the docs-example landing pass.

Point generated-code references at the complete commit range from
the pre-remediation branch head.

Prompt-IO: ai/prompt-io/opencode/20260828T200822Z_0be872ff_prompt_io.md

(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))
Print the discovered service's remote channel address instead of
the default `Portal` object repr.

Review: #512 (comment)

(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

At least one updated example introduces a concrete static-typing mismatch (accept_addr annotated too narrowly) that should be corrected to keep the examples type-consistent.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 42/42 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread examples/uds_transport_actor_tree.py Outdated
@goodboy goodboy added the code-style general look-n-feel, formatting, linting, types label Aug 30, 2026
Match `Actor.accept_addr`'s declared `tuple[str, int|str]` contract
instead of narrowing its second item to the UDS-specific string path.

Review: #512 (comment)

(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))
@goodboy
goodboy merged commit f220b46 into main Aug 30, 2026
8 checks passed
@goodboy
goodboy deleted the wkt/big_boi_docs_472_follow_ups branch August 30, 2026 02:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

code-style general look-n-feel, formatting, linting, types docs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants