ActrRef

Struct ActrRef 

Source
pub struct ActrRef<W: Workload> { /* private fields */ }
Expand description

ActrRef - Lightweight reference to a running Actor

This is the primary handle returned by ActrNode::start().

§Code Generation Pattern

actr-cli code generator will generate type-safe RPC methods for ActrRef.

§Proto Definition

service EchoService {
  rpc Echo(EchoRequest) returns (EchoResponse);
  rpc Ping(PingRequest) returns (PingResponse);
}

§Generated Code (in generated/echo_service_actr_ref.rs)

use actr_runtime::ActrRef;
use super::echo_service_actor::{EchoServiceWorkload, EchoServiceHandler};
use super::echo::{EchoRequest, EchoResponse, PingRequest, PingResponse};

impl<T: EchoServiceHandler> ActrRef<EchoServiceWorkload<T>> {
    /// Call Echo RPC method
    pub async fn echo(&self, request: EchoRequest) -> ActorResult<EchoResponse> {
        self.call(request).await
    }

    /// Call Ping RPC method
    pub async fn ping(&self, request: PingRequest) -> ActorResult<PingResponse> {
        self.call(request).await
    }
}

§Usage in Shell

use generated::echo_service_actr_ref::*;  // Import ActrRef extensions

let actr = node.start().await?;

// Type-safe RPC calls (generated methods)
let response = actr.echo(EchoRequest {
    message: "Hello".to_string(),
}).await?;

// Or use generic call() method
let response: EchoResponse = actr.call(EchoRequest { ... }).await?;

§Design Rationale

Why bind RPC methods to ActrRef?

  1. Type Safety: Compiler checks request/response types
  2. Auto-completion: IDE shows available RPC methods
  3. No target needed: ActrRef already knows its target Actor
  4. Symmetric to Context: Similar to Context extension pattern

Comparison with Context pattern:

AspectContext (in Workload)ActrRef (in Shell)
CallerWorkloadShell
TargetAny Actor (needs target param)This Workload (fixed)
Methodctx.call(target, req)actr.echo(req)
GenerationExtension traitConcrete impl

Implementations§

Source§

impl<W: Workload> ActrRef<W>

Source

pub fn actor_id(&self) -> &ActrId

Get Actor ID

Source

pub async fn discover_route_candidates( &self, target_type: &ActrType, candidate_count: u32, ) -> ActorResult<Vec<ActrId>>

Discover remote actors of the specified type via signaling server.

This method implements the full runtime compatibility negotiation workflow:

  1. Fast Path: Check compat.lock.toml for cached negotiation results
  2. Ideal Path: Read fingerprint from Actr.lock.toml and request exact match
  3. Negotiation: If no exact match, server performs compatibility analysis
  4. Result: Returns candidates with compatibility info, updates caches

The fingerprint is automatically obtained from the Actr.lock.toml file loaded during ActrSystem::attach().

§Arguments
  • target_type: The ActrType of the target service to discover
  • candidate_count: Maximum number of candidates to return
§Returns

A list of compatible ActrId candidates.

Source

pub async fn call<R>(&self, request: R) -> ActorResult<R::Response>
where R: RpcRequest,

Call Actor method (Shell → Workload RPC)

This is a generic method used by code-generated RPC methods. Most users should use the generated methods instead.

§Example
// Generic call
let response: EchoResponse = actr.call(EchoRequest {
    message: "Hello".to_string(),
}).await?;

// Generated method (preferred)
let response = actr.echo(EchoRequest {
    message: "Hello".to_string(),
}).await?;
Source

pub async fn call_raw( &self, route_key: String, request_bytes: Bytes, timeout_ms: i64, payload_type: PayloadType, ) -> ActorResult<Bytes>

Call Actor method using route_key and request bytes (for language bindings)

This is a non-generic version of call() that accepts route_key and raw bytes, making it suitable for language bindings (e.g., Python) that don’t have access to Rust’s generic RpcRequest trait.

§Parameters
  • route_key: Route key string (e.g., “package.Service.Method”)
  • request_bytes: Request protobuf bytes
  • timeout_ms: Timeout in milliseconds
  • payload_type: Payload transmission type
§Returns

Response protobuf bytes

Source

pub async fn tell_raw( &self, route_key: String, message_bytes: Bytes, payload_type: PayloadType, ) -> ActorResult<()>

Send one-way message using route_key and message bytes (for language bindings)

This is a non-generic version of tell() that accepts route_key and raw bytes, making it suitable for language bindings (e.g., Python) that don’t have access to Rust’s generic RpcRequest trait.

§Parameters
  • route_key: Route key string (e.g., “package.Service.Method”)
  • message_bytes: Message protobuf bytes
  • payload_type: Payload transmission type
§Returns

Unit (fire-and-forget, no response)

Source

pub async fn tell<R>(&self, message: R) -> ActorResult<()>

Send one-way message to Actor (Shell → Workload, fire-and-forget)

Unlike call(), this method does not wait for a response. Use this for notifications or commands that don’t need acknowledgment.

§Example
// Send notification without waiting for response
actr.tell(LogEvent {
    level: "INFO".to_string(),
    message: "User logged in".to_string(),
}).await?;

// Generated method (if codegen supports tell)
actr.log_event(LogEvent { ... }).await?;
§Performance
  • Latency: ~10μs (in-process, zero serialization)
  • No blocking: Returns immediately after sending
  • No response: Caller won’t know if message was processed
Source

pub fn shutdown(&self)

Trigger Actor shutdown

This signals the Actor to stop, but does not wait for completion. Use wait_for_shutdown() to wait for cleanup to finish.

Source

pub async fn wait_for_shutdown(&self)

Wait for Actor to fully shutdown

This waits for the shutdown signal to be triggered. All background tasks will be aborted when the last ActrRef is dropped.

Source

pub fn is_shutting_down(&self) -> bool

Check if Actor is shutting down

Source

pub async fn wait_for_ctrl_c_and_shutdown(self) -> ActorResult<()>

This consumes the ActrRef and waits for signal (Ctrl+C / SIGTERM) , then triggers shutdown.

§Example
let actr = node.start().await?;
actr.wait_for_ctrl_c_and_shutdown().await?;

Trait Implementations§

Source§

impl<W: Workload> Clone for ActrRef<W>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl<W> Freeze for ActrRef<W>

§

impl<W> !RefUnwindSafe for ActrRef<W>

§

impl<W> Send for ActrRef<W>

§

impl<W> Sync for ActrRef<W>

§

impl<W> Unpin for ActrRef<W>

§

impl<W> !UnwindSafe for ActrRef<W>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more