Commit Graph

7 Commits (b9dca728d93d9dcf0038e254b15fb24d21e6fbdc)

Author SHA1 Message Date
Gud Boi bb0a9b3c93 Remove `run_in_actor()` + the ria reap cluster
The final excision of #477: with zero in-repo callers left (all
tests/examples/docs migrated to `to_actor.run()` et al) the
entire legacy one-shot machinery drops out,

- `runtime/_supervise.py`: `ActorNursery.run_in_actor()`, the
  `._cancel_after_result_on_exit` portal-set and the
  `_reap_ria_portals()` teardown-reaper (both its happy-path
  block-exit call AND the error-path snapshot + 0.5s-bounded
  collection) are deleted — one-shot result-waiting now lives
  entirely in the caller's task via `to_actor.run()`, whose
  enclosing cancel-scope bounds the wait by construction (the
  correct-scoping fix for the unbounded-reap hang class; the
  `d1fb4a1a` guard test now passes structurally).
- `runtime/_portal.py`: `Portal._submit_for_result()`,
  `._expect_result_ctx`, `._final_result_msg/_pld`,
  `.wait_for_result()` + the deprecated `.result()` alias are
  gone — a `Portal` no longer has any "main result" notion.
  NB `Context.wait_for_result()` is a different (very alive)
  API and is untouched.
- `spawn/_spawn.py`: `exhaust_portal()` +
  `cancel_on_completion()` (the reaper tasks) deleted; backend
  comment sweeps in `_trio.py`/`_mp.py`.
- `_exceptions.py`: the `NoResult` sentinel dies with its lone
  reader.
- `tests/test_ringbuf.py`: drop a daemon-portal `.result()`
  call that was already a warn + `NoResult` no-op (the ctx-acm
  exit does the real result-wait); unshadow the 2nd `sctx` as
  `rctx`.
- comment/docstring x-ref sweeps: `msg/types.py`,
  `_context.py`, `to_actor/`, `tests/test_to_actor.py`.

Gate: `test_to_actor test_spawning test_cancellation
test_infected_asyncio test_local test_rpc` = 81 passed,
3 xfailed on `trio`; +`test_ringbuf` = 70 passed, 3 skipped,
3 xfailed on `mp_spawn`.

(this patch was generated in some part by [`claude-code`][claude-code-gh])
[claude-code-gh]: https://github.com/anthropics/claude-code
2026-08-25 19:16:32 -04:00
Gud Boi 617ca1de43 Clarify `run()` actor lifetime management
`run()` described its actor-selection kwargs as placement controls,
but they determine who owns the actor lifetime and whether an existing
actor is reused or a new one is spawned.

Use lifetime-management terminology in the parameter comments and
docstring, and identify the existing-actor handle as `portal: Portal`.

Review: PR #481 (goodboy)
https://github.com/goodboy/tractor/pull/481#pullrequestreview-5012942328

(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))
2026-08-24 22:37:49 -04:00
Gud Boi 9373e9434d Inline `functools.Placeholder` lookup
Partial normalization assigned the optional Python 3.14 placeholder
sentinel separately from its only conditional consumer.

Bind the sentinel with a walrus expression directly in the guard while
retaining the `getattr()` fallback for older Python versions.

Review: PR #481 (goodboy)
https://github.com/goodboy/tractor/pull/481#pullrequestreview-5012942328

Prompt-IO: ai/prompt-io/opencode/20260825T021319Z_ce430fca_prompt_io.md

(this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`))
2026-08-24 22:19:21 -04:00
Gud Boi 20e89334c0 Reject misplaced empty `runtime_kwargs`
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)
https://github.com/goodboy/tractor/pull/481#pullrequestreview-4956692120

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`))
2026-08-21 15:03:34 -04:00
Gud Boi fe0a724d10 Use linked contexts in `to_actor.run()`
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)
https://github.com/goodboy/tractor/pull/481#pullrequestreview-4956692120

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`))
2026-08-21 15:03:34 -04:00
Gud Boi 49213d170e Reap `to_actor.run()` children before return
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)
https://github.com/goodboy/tractor/pull/481#discussion_r3514759131

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`))
2026-08-21 15:03:34 -04:00
Gud Boi 3b0b37dcb4 Add `tractor.to_actor` one-shot task API subpkg
First cut at the `to_thread`/`to_process`-style "run it over there"
wrapper layer from issue #477: a single-remote-task invocation API
decoupled from the `ActorNursery` spawn machinery, composed purely
from the lower level daemon-actor + portal primitives,

- `to_actor.run(fn, **fn_kwargs)` spawns a subactor via
  `ActorNursery.start_actor()`, schedules `fn` as its lone task
  with `Portal.run()` and ALWAYS reaps it via a `finally`-scoped
  `Portal.cancel_actor()` (whose bounded cancel-req wait is
  internally shielded so the reap also runs under caller-scope
  cancellation).
- remote errors raise directly in the caller's task as boxed
  `RemoteActorError`s, moving error collection/propagation up into
  whatever local `trio` scope encloses the call.
- "placement" opts: `portal=` reuses a running actor (no
  spawn/reap), `an=` spawns from a caller-managed actor-nursery,
  neither opens a private call-scoped `open_nursery()` (implicitly
  booting the runtime, tunable via pass-through `runtime_kwargs`).
- fail-fast validation BEFORE any spawn: non-streaming async fn
  only (same constraint as `Portal.run()`), `portal=`/`an=` mutual
  exclusion and no `runtime_kwargs` alongside a placement opt.

Also,
- x-ref the successor API from `.run_in_actor()`'s deprecation TODO
  + docstring; emitting a formal `DeprecationWarning` waits on
  migrating in-repo usage.
- log prompt-io provenance per NLNet policy incl. the driver prompt
  file.

Prompt-IO: ai/prompt-io/claude/20260702T154255Z_65bf9df5_prompt_io.md

(this patch was generated in some part by [`claude-code`][claude-code-gh])
[claude-code-gh]: https://github.com/anthropics/claude-code
2026-08-21 15:03:34 -04:00