Skip to content

Type-check RPC Start params from endpoint signatures #514

Description

@goodboy

Problem

RPC endpoint argument contracts are only partially represented today.

@tractor.context records the endpoint's inspect.Signature, but a
dialog's pld_spec does not cover Start arguments and the captured
signature is not yet used to derive a typed Start message contract.
Caller-facing APIs also cannot consistently preserve the endpoint's full
positional, keyword-only, defaulted, and variadic signature for static
checking.

PR #481 moved to_actor.run() toward this model with TypeVarTuple and
local inspect.Signature.bind() validation. PR #484 established
functools.partial() as the way to bind target keyword arguments without
colliding with actor-runtime options. The remaining work is to carry that
contract through the RPC protocol instead of treating it as a local
one-shot special case.

Goal

Derive an RPC endpoint's Start parameter contract from its callable
signature and annotations, preserving that signature at the caller where
Python's typing machinery permits it.

The intended direction is:

  • use ParamSpec, Concatenate, PEP 695 type parameters, or the nearest
    workable equivalent to preserve caller-facing endpoint signatures;
  • validate arguments sender-side before transmitting Start when the
    callable and its signature are locally available;
  • validate against the same contract at endpoint dispatch so dynamically
    addressed or remote-only targets remain safe;
  • report argument-contract failures consistently without starting an
    invalid RPC task;
  • generate or associate the corresponding typed Start message schema
    rather than adding a second unrelated validation model.

Design questions

  • Which APIs can retain a useful ParamSpec: to_actor.run(),
    Portal.run(), Portal.open_context(), and/or @tractor.context?
  • How should the injected Context parameter be removed from the
    caller-facing signature?
  • How should defaults, keyword-only parameters, *args, **kwargs, and
    functools.partial() targets map onto Start fields?
  • What signature metadata, if any, must cross the wire for targets named by
    NamespacePath or string rather than supplied as local callables?
  • Should mismatches use local TypeError, MsgTypeError, or a dedicated
    protocol error at each validation boundary?
  • How do we avoid redundant encode/decode work while retaining useful
    sender-side failures for control messages?

Acceptance direction

  • Static typing preserves valid endpoint calls and rejects representative
    invalid positional and keyword argument combinations.
  • Locally known invalid arguments fail before a Start message is sent.
  • Endpoint dispatch checks remote-only or dynamically resolved targets
    before scheduling their RPC task.
  • Local and remote failure behavior is documented and covered for both
    one-shot and context endpoints.
  • Existing to_actor.run() and functools.partial() behavior from Add tractor.to_actor one-shot task API subpkg #481 and
    Drop run_in_actor() + the ria reap-cluster #484 remains supported.

Related work

Existing implementation notes live around tractor._context.context(),
tractor.msg.Start, and tractor.to_actor.run().

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions