Skip to content

Add tractor.to_actor one-shot task API subpkg - #481

Open
goodboy wants to merge 20 commits into
mainfrom
wkt/to_actor_subpkg
Open

Add tractor.to_actor one-shot task API subpkg#481
goodboy wants to merge 20 commits into
mainfrom
wkt/to_actor_subpkg

Conversation

@goodboy

@goodboy goodboy commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Add tractor.to_actor one-shot task API subpkg

Motivation

First cut at resolving #477: the .run_in_actor() "one shot"
single-remote-task style API is coupled to ActorNursery internals
(the secondary ._ria_nursery, portal result-marking sets and
backend-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 a tractor.to_actor subpkg
composed purely from the lower level daemon-spawn + portal
primitives, moving error collection/propagation up into whatever
local trio scope encloses the call — and paving the way to fully
drop the ._ria_nursery machinery.

Summary of changes

  • new tractor.to_actor subpkg exporting run(fn, **fn_kwargs) -> Any: spawn a subactor via ActorNursery.start_actor(), schedule
    fn as its lone remote task with Portal.run(), block waiting on
    and return its result, ALWAYS reaping the subactor via a
    finally-scoped Portal.cancel_actor(). Remote errors raise
    directly in the caller's task as boxed RemoteActorErrors.
    "Placement" opts: portal= re-uses 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 pre-spawn validation: non-streaming async fn only,
    portal=/an= mutually exclusive, no runtime_kwargs alongside a
    placement opt. Legacy .run_in_actor() behavior untouched; its
    TODO/docstring now x-ref the successor API.
  • tests/test_to_actor.py: 11-test suite covering all placement
    variants, remote-error relay (bare + inside a caller-managed an),
    portal re-use w/o implicit reap, the concurrent "worker-pool-ish"
    pattern (local trio task nursery scheduling one-shots against a
    shared 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-implicit
    one-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),

  • migrate in-repo .run_in_actor() usage (tests, examples, docs)
    to to_actor.run()
  • emit a DeprecationWarning from .run_in_actor() (blocked on
    ^)
  • drop the ._ria_nursery + ._cancel_after_result_on_exit
    machinery — in progress on the stacked drop_ria_nursery branch
    (result-waiting being re-scoped into the to_actor layer), see
    ai/conc-anal/ria_nursery_removal_plan.md
  • docs nod from the .run_in_actor() autodoc entry
  • maybe: the worker-pool "sugar" API layer (Do we need a streaming equivalent (sugar) for .run_in_actor()? #172)

(this pr content was generated in some part by claude-code)

Copilot AI review requested due to automatic review settings July 2, 2026 16:44

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.

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 from run_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 thread tractor/to_actor/_api.py Outdated
Comment thread ai/prompt-io/prompts/issue_477.md
@goodboy goodboy changed the title Wkt/to actor subpkg Add tractor.to_actor one-shot task API subpkg Jul 2, 2026
@goodboy
goodboy force-pushed the wkt/to_actor_subpkg branch from 5cd190c to a34aaf9 Compare July 3, 2026 01:36
@goodboy
goodboy force-pushed the wkt/to_actor_subpkg branch from a34aaf9 to 4151b95 Compare August 18, 2026 02:06

@goodboy goodboy left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

[P1] Do not treat a cancel acknowledgement as process reaping

tractor/to_actor/_api.py:96-112 | confidence: high | category: concurrency

Portal.cancel_actor() only requests runtime cancellation. It can return False after its bounded timeout, and even True does not mean the subprocess was joined or removed from ActorNursery._children.

Consequences:

  • Private placement can hang during nursery exit when cancellation is not acknowledged.
  • Caller-managed an= placement returns while child monitor tasks and process records remain alive.
  • Repeated one-shots through a long-lived nursery accumulate resources instead of being reaped per call.

The existing Copilot thread correctly identifies part of this problem.

Recommendation: add an owned-child operation that cancels, escalates if necessary, waits for process termination, and removes that specific child before to_actor.run() returns. Add timeout and immediate-an._children cleanup tests.

[P2] Separate remote function arguments from placement controls

tractor/to_actor/_api.py:115-145 | confidence: high | category: API correctness

The API consumes names such as name, portal, an, loglevel, and runtime_kwargs before building fn_kwargs. A valid remote function cannot receive an argument with any of those names.

For example, to_actor.run(greet, name='Alice') names the actor but invokes greet() without its required name.

Recommendation: accept remote arguments through an explicit mapping or otherwise create a collision-free calling convention. Add coverage for functions using reserved parameter names.

[P2] Cancel portal-reused remote tasks when the caller is cancelled

tractor/to_actor/_api.py:183-192 | confidence: high | category: cancellation

The portal= path directly awaits Portal.run(). If the local caller is cancelled, no Context.cancel() request is sent, so the remote task can continue after its calling task has exited.

Recommendation: retain the submitted Context and shield a task-level cancellation request during local cancellation. Do not cancel the caller-owned actor itself.

[P3] Reject runtime options that cannot take effect

tractor/to_actor/_api.py:168-181,217-218 | confidence: high | category: API correctness

When already inside an actor runtime without an= or portal=, runtime_kwargs reaches open_nursery(), whose existing-runtime path ignores those root-runtime options. Configuration can therefore appear accepted without taking effect. The truthiness check also permits runtime_kwargs={} alongside placement options.

Recommendation: reject runtime_kwargs whenever no new root runtime will be created and validate with runtime_kwargs is not None.

Review State

  • #481 is not landing-ready due to the P1 lifecycle issue.
  • Correctness thread r3514759131 remains unresolved and is valid.
  • Prompt-provenance thread r3514759173 should be declined: the time-specific instruction is historical input and rewriting it would falsify the provenance record.
  • Fresh CI is still running.
  • The source TODO marker changed from [ ] to [x]; confirm that was an intentional human-owned state transition.

Checks run: static inspection of the exact PR diff, callers, process monitors, cancellation paths, tests, and current GitHub review state.

Checks not run: local tests and analyzers were not authorized; fresh GitHub CI is currently exercising the rebased head.

Scope: PR #481, base/merge-base 4e27dcde, head 4151b956, 9 changed files. Prompt provenance was excluded from semantic code review except for triaging its review comment.

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

goodboy added a commit that referenced this pull request Aug 19, 2026
Give each `ActorNursery` child its own reap request and
completion event. Owned one-shots now wait for process joining and
bookkeeping removal before returning.

Escalate unacknowledged cancellation with `proc.kill()` after an
active debugger releases. Latch nursery-wide teardown for monitors
that finish startup late, and snapshot children before cancellation
checkpoints permit concurrent removal.

Cover immediate managed-nursery cleanup, failed cancel
acknowledgements and late monitor registration across Trio TCP/UDS
and `mp_spawn`.

Caught-during: review remediation
Found-via: `/run-tests` test_late_child_reap_registration_is_released

Review: PR #481 (copilot-pull-request-reviewer)
#481 (comment)

Prompt-IO: ai/prompt-io/opencode/20260818T031532Z_4151b956_prompt_io.md

(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))
goodboy added a commit that referenced this pull request Aug 19, 2026
`SendStream.send_all()` can raise `trio.Cancelled` after writing an
arbitrary prefix of the four-byte length header and payload. The
peer can no longer distinguish a following msg boundary.

Close the stream under a shield before propagating cancellation so
callers can not append another msg to an indeterminate byte stream.

Caught-during: review remediation
Found-via: prospective P2 cancellation review

Review: PR #481 (opencode)
#481 (review)

Prompt-IO: ai/prompt-io/opencode/20260818T193001Z_bf06b4f8_prompt_io.md

(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))
goodboy added a commit that referenced this pull request Aug 19, 2026
Derive the `Actor._contexts` key from each `Context` in one
idempotent `Actor._drop_context()` helper instead of reconstructing
the peer UID and CID at every teardown site.

Use the helper for caller-side context exit and preserve a strict
identity assertion when the callee-side RPC task deregisters
itself. Keep channel closure and cancellation shielding with their
existing lifecycle owners.

Caught-during: review remediation
Found-via: staged P2 lifecycle review

Review: PR #481 (opencode)
#481 (review)

Prompt-IO: ai/prompt-io/opencode/20260818T193002Z_bf06b4f8_prompt_io.md

(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))
goodboy added a commit that referenced this pull request Aug 19, 2026
Cancellation after `Start` publication but before `StartAck` can
strand the caller context and leave its remote task running.

Make one shielded, bounded task-cancel request before dropping
local startup state. Keep the private `cancel_on_startup` policy
outside public target kwargs and disable it for the `_cancel_task`
RPC itself so cleanup can not recursively cancel its own startup.

Release each private helper context on exit and prove the
caller-owned actor remains reusable after controlled startup
cancellation.

Caught-during: review remediation
Found-via: `/run-tests` test_cancel_during_context_startup

Review: PR #481 (opencode)
#481 (review)

Prompt-IO: ai/prompt-io/opencode/20260818T193003Z_bf06b4f8_prompt_io.md

(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))
goodboy added a commit that referenced this pull request Aug 19, 2026
`Actor.start_remote_task()` registers its caller context before
sending `Start`, but only cancellation cleaned that state.
Encoding, ack timeout, malformed ack and remote authorization
errors leaked it.

Protect the complete send, acknowledgement and validation phase.
Track successful publication, make a remote cancellation attempt
only when protocol-safe and always release the local context while
preserving the original startup error.

Cover both pre-publication serialization failure and a remote
`ModuleNotExposed` rejection without damaging a reused portal.

Caught-during: review remediation
Found-via: `/run-tests` startup-failure regressions

Review: PR #481 (opencode)
#481 (review)

Prompt-IO: ai/prompt-io/opencode/20260818T193004Z_bf06b4f8_prompt_io.md

(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))
goodboy added a commit that referenced this pull request Aug 19, 2026
Pass target inputs positionally and normalize every retained
`functools.partial()` layer, including Python 3.14 Placeholder
binding. Validate the complete target signature before startup.

Route each ordinary async fn through a static `@context` endpoint
so remote results, errors and caller cancellation remain linked.
Send namespace and function components separately, then resolve
through `Actor._get_rpc_func()` so the RPC module allowlist remains
authoritative. Retain client-created `NamespacePath` refs so
`to_tuple()` does not re-import their callable.

Owned actors enable the endpoint's `__name__` directly. Keep
`to_actor.MODULE` as the importer-facing alias used by caller-owned
portals while retaining the target module's authorization boundary.

Cover all placement modes, nested partials, argument collisions,
linked cancellation, remote errors and authorization failures.

Caught-during: review remediation
Found-via: `/run-tests` portal cancellation regression

Review: PR #481 (opencode)
#481 (review)

Prompt-IO: ai/prompt-io/opencode/20260818T193005Z_bf06b4f8_prompt_io.md

(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))
goodboy added a commit that referenced this pull request Aug 19, 2026
Treat `runtime_kwargs` as provided whenever it is not `None`.
Previously an empty dict bypassed placement validation and was
silently ignored when `an` or `portal` selected an existing runtime.

Reject both placement modes before actor startup for empty and
configured runtime kwargs while preserving empty-dict use when
`to_actor.run()` owns its private runtime.

Caught-during: review remediation
Found-via: `/code-review` P3 option-validation finding

Review: PR #481 (opencode)
#481 (review)

Prompt-IO: ai/prompt-io/opencode/20260819T020757Z_b38efed7_prompt_io.md

(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))
@goodboy goodboy linked an issue Aug 19, 2026 that may be closed by this pull request
11 tasks
@goodboy goodboy added enhancement New feature or request testing docs api supervision cancellation SC teardown semantics and anti-zombie semantics examples spawning of processes, (shm) threads, tasks on varied (OS-specific) backends labels Aug 19, 2026
goodboy added a commit that referenced this pull request Aug 20, 2026
The rendered guides and executable examples still taught the legacy
`ActorNursery.run_in_actor()` result-portal model even though #481
adds its blocking, linked-context replacement.

Deats,
- migrate one-shots to direct results through `to_actor.run()`
- preserve named target inputs with `functools.partial()`
- use daemon actors where reciprocal dialogs need longer lifetimes
- link the new API from core, asyncio and clustering references
- retain only explicit legacy/removal notes

Prompt-IO: ai/prompt-io/opencode/20260820T023005Z_88a23449_prompt_io.md

(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))
@goodboy
goodboy requested a lite review from Copilot August 20, 2026 16:22

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.

Pull request overview

Copilot reviewed 73 out of 73 changed files in this pull request and generated no new comments.

Suppressed comments (3)

tractor/runtime/_supervise.py:679

  • ActorNursery.cancel() never sets self._cancelled_caught to True on the successful (non-timeout) path; the else: branch is currently a no-op. This makes ActorNursery.cancelled_caught permanently False and contradicts the property/docstring intent.
    tractor/runtime/_supervise.py:677
  • In the cancel-timeout fallback (cs.cancelled_caught), the log says "Hard killing" but the code still uses proc.terminate(). If this path is meant to guarantee teardown under misbehaving children, prefer proc.kill() when available (SIGKILL / non-ignorable), and only fall back to terminate() when .kill() is unavailable.
    tractor/runtime/_supervise.py:93
  • The _try_cancel_then_kill() docstring still claims it always calls Portal.cancel_actor(raise_on_timeout=True), but the implementation now passes raise_on_timeout=not debug_protected. Updating the docstring avoids misleading readers about when timeouts are expected to raise/escalate.

The Darwin-only debugger skip in `49fc92b0` passed the raw
`CI=true` env string to `skipif`, so `pytest` evaluated `true`
as Python source and failed at setup instead of skipping the
issue #320 node.

Cast `_ci_env` through `bool()` so the marker always receives
a boolean while retaining Linux coverage.

Prompt-IO: ai/prompt-io/opencode/20260820T135125Z_9f99043b_prompt_io.md

(this patch was generated in some part by `opencode` using
`gpt-5.6-sol` (`openai`))
The frame-publication shield added in `88a23449` checks for
pending cancellation only after a successful write. If actor
teardown closes the stream first, `ClosedResourceError` escaped
as `TransportClosed` and could defeat the caller's cancel scope.

Check for pending cancellation on the transport-error path before
normalizing the close. Genuine stream errors retain their existing
translation when no cancellation is active.

The cancellation-first path can swap which nested debugger
intermediary renders as the immediate source vs. relay. Keep
assertions over both actor levels while accepting either valid role.

Prompt-IO: ai/prompt-io/opencode/20260820T143845Z_559fd0f1_prompt_io.md

(this patch was generated in some part by `opencode` using
`gpt-5.6-sol` (`openai`))
The guides described every placement as spawn-run-reap and omitted
the trampoline allowlist required when reusing an existing actor.

- distinguish call-owned children from caller-owned portal actors
- document stable module-global target addresses and allowlists
- add the #477 feature news fragment

(this patch was generated in some part by `opencode` using
`gpt-5.6-sol` (`openai`))
A cancel RPC could stall forever in complete-frame transport
shielding before the peer received it, bypassing the outer ack
timeout and blocking graceful supervision.

- thread one absolute deadline from `Portal.cancel_actor()` through
  the private `Start` publication path
- force-close a partial-frame stream before releasing its send lock
- keep ordinary sends unbounded and preserve pending cancellation
- document the current `Start -> StartAck -> CancelAck` exchange and
  link the dedicated `Cancel` msg follow-up in #506
- cover partial publication and the shared send/ack timeout budget

Prompt-IO: ai/prompt-io/opencode/20260821T023537Z_ae6f2ac3_prompt_io.md

(this patch was generated in some part by `opencode` using
`gpt-5.6-sol` (`openai`))
A child could pass the early `.start_actor()` guard, miss the
`.cancel()` child snapshot and register afterward. Its monitor
inherited a reap request without runtime cancellation and could wait
forever.

- publish child/reap events before sampling `_cancel_called`
- make MP abort before `proc.start()` when cancellation won
- kill a Trio child opened after cancellation won registration
- reject starts begun after nursery cancellation is already visible
- add deterministic registration and MP no-start regressions
- drop the touched Trio backend's stale `get_runtime_vars` import

Prompt-IO: ai/prompt-io/opencode/20260821T040803Z_3c1bbe73_prompt_io.md

(this patch was generated in some part by `opencode` using
`gpt-5.6-sol` (`openai`))
Target validation moved to a follow-up branch, so the guide should not
claim unstable callable forms are rejected before actor startup.

Describe module-global functions and `functools.partial()` wrappers
as portable stable-address forms without promising absent enforcement.

(this patch was generated in some part by `opencode` using
`gpt-5.6-sol` (`openai`))
@goodboy
goodboy force-pushed the wkt/to_actor_subpkg branch from 70f497b to ce38cb6 Compare August 21, 2026 19:03

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

i think this was added by accident maybe?

Comment thread docs/guide/spawning.rst
- the child is *auto-cancelled* once its "main" result lands;
at nursery exit these run-once children are always reaped
first (causality_ is paramount!).
- targets cross IPC as ``module:name`` references, so portable calls

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

maybe we should clarify this limitation, that it's due to our enable_modules: list requirement in (sub)actors such that arbitrarily defined fns can't be invoked remotely without prior permission handed to the runtime.

)
)

await trio.sleep(0.5)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

this sleep is from the orig which has an async call and i presume the sleep was for naive syncing? maybe it can be dropped since we moved to blocking semantics on the name_error caller?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

maybe we need a comment like below explaining this yields to the sched so that breakpoint_forever caller task gets invoked; presuming that's why it's still necessary.

tn.start_soon(portal.run, name_error)
tn.start_soon(portal1.run, spawn_error)

# yield to the bg tasks so both RPC requests are

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

ahh ok, so the sleep i quiffer earlier likely needs this as well?

async with (
tractor.open_nursery(
debug_mode=True,
enable_transports=['uds'], # TODO, apss this via osenv?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

typo apply we can prolly fix

async with (
tractor.open_nursery(
debug_mode=True,
# loglevel='debug' # ?XXX required?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

i presume not required since it's been sitting here so long with green CI 😛

await trio.sleep(1/50000/50)

return os.getpid()
return pid

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

maybe a comment indicating that the return val is what's returned to the to_actor.run() caller side?

@goodboy goodboy Aug 21, 2026

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

hmm maybe we should relable this file as concurrent_toactor_primes.py?
if it's basically the same as concurrent_actors_primes.py but using the to_actor.run() api. also follow-up note, concurrent_actors_primes.py definitely needs an update after #484 (and if that pr doesn't already do that) to conventional naming (an, tn) and per /py-codestyle.

for name in ('donny', 'gretchen')
}

async def run_and_print(name: str, other_actor: str):

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

switch this to multiline arg, per line style.


async def run_and_print(name: str, other_actor: str):
print(
await portals[name].run(

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

maybe a comment indicating this is Portal.run() usage?

Comment thread nooz/477.feature.rst
@@ -0,0 +1,3 @@
Add ``tractor.to_actor.run()`` for Trio-style one-shot async calls in

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

ahh nice i've totes forgot about doing changelog entries 🫣, we should keep this up 👍🏼

)
child.sendline('c')
child.expect(EOF)
assert_before(

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

wait these were removed but are never checked any more orrr?

]
if not no_capfd:
expect_on_teardown += [
# 'Shutting down actor runtime',

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

aww i always like this little cutie, but i guess it makes sense to be all "professional" in our msgs now since we're becoming a real project Bp

)
packed: dict[str, object] = {}

def pack_overrun(

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

maybe a comment that this mocked fn is used to avoid actually raising the error, presuming that's why it's actually being defined over our real helper fn?

payload,
hide_tb=hide_tb,
)
if isinstance(payload, tractor.msg.Start):

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

why do we need an isinstance check if we only ever call this once with a Start msg?

try:
await ctx.started()
await trio.sleep_forever()
finally:

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

should we maybe be ensuring a Cancelled (or ContextCancelled) is actually raised explicitly instead of presuming?


def _non_registration_contexts(
actor: Actor,
) -> dict[tuple, str]:

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

doc string indicating this simply returns all registered actor contexts except the registry calls?


'''
async with tractor.open_nursery() as an:
actor = tractor.current_actor()

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

actually for any examples/tests we're updating in this PR we might as well add terse typing at least from tractor.* if possible.

portal: tractor.Portal = await an.start_actor(
'module_error_worker',
)
contexts_before = _non_registration_contexts(actor)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

yeah particularly for helper fns being added to test suites it'd be good to see return types for easier human passes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api cancellation SC teardown semantics and anti-zombie semantics docs enhancement New feature or request examples spawning of processes, (shm) threads, tasks on varied (OS-specific) backends supervision testing

Projects

None yet

2 participants