Context

Trait Context 

Source
pub trait Context: Send + Sync {
    // Required methods
    fn self_id(&self) -> &ActrId;
    fn caller_id(&self) -> Option<&ActrId>;
    fn request_id(&self) -> &str;
    fn call<'life0, 'life1, 'async_trait, R>(
        &'life0 self,
        target: &'life1 Dest,
        request: R,
    ) -> Pin<Box<dyn Future<Output = ActorResult<R::Response>> + Send + 'async_trait>>
       where R: 'async_trait + RpcRequest,
             Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn tell<'life0, 'life1, 'async_trait, R>(
        &'life0 self,
        target: &'life1 Dest,
        message: R,
    ) -> Pin<Box<dyn Future<Output = ActorResult<()>> + Send + 'async_trait>>
       where R: 'async_trait + RpcRequest,
             Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn register_stream<'life0, 'async_trait, F>(
        &'life0 self,
        stream_id: String,
        callback: F,
    ) -> Pin<Box<dyn Future<Output = ActorResult<()>> + Send + 'async_trait>>
       where F: Fn(DataStream, ActrId) -> BoxFuture<'static, ActorResult<()>> + Send + Sync + 'static + 'async_trait,
             Self: 'async_trait,
             'life0: 'async_trait;
    fn unregister_stream<'life0, 'life1, 'async_trait>(
        &'life0 self,
        stream_id: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = ActorResult<()>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn send_data_stream<'life0, 'life1, 'async_trait>(
        &'life0 self,
        target: &'life1 Dest,
        chunk: DataStream,
    ) -> Pin<Box<dyn Future<Output = ActorResult<()>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn discover_route_candidate<'life0, 'life1, 'async_trait>(
        &'life0 self,
        target_type: &'life1 ActrType,
    ) -> Pin<Box<dyn Future<Output = ActorResult<ActrId>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn register_media_track<'life0, 'async_trait, F>(
        &'life0 self,
        track_id: String,
        callback: F,
    ) -> Pin<Box<dyn Future<Output = ActorResult<()>> + Send + 'async_trait>>
       where F: Fn(MediaSample, ActrId) -> BoxFuture<'static, ActorResult<()>> + Send + Sync + 'static + 'async_trait,
             Self: 'async_trait,
             'life0: 'async_trait;
    fn unregister_media_track<'life0, 'life1, 'async_trait>(
        &'life0 self,
        track_id: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = ActorResult<()>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn send_media_sample<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        target: &'life1 Dest,
        track_id: &'life2 str,
        sample: MediaSample,
    ) -> Pin<Box<dyn Future<Output = ActorResult<()>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
}
Expand description

Context - Actor execution context interface

Defines the complete interface for Actor interaction with the system, including:

  • Context data access (self_id, request_id, etc.)
  • Communication capabilities (call, tell)

§Design Principles

  • Interface only: Framework does not provide implementation, runtime implements
  • Generic parameter: User code uses <C: Context> instead of &dyn Context
  • Zero virtual calls: Static dispatch via generic monomorphization

§Implementation Requirements

Runtime must implement this trait and use enum dispatch or other zero-overhead mechanisms internally (avoiding virtual function calls).

§Example

async fn my_handler<C: Context>(ctx: &C) {
    // Access data
    let id = ctx.self_id();

    // Type-safe call
    let response = ctx.call(&target, request).await?;
}

Required Methods§

Source

fn self_id(&self) -> &ActrId

Get the current Actor’s ID

Source

fn caller_id(&self) -> Option<&ActrId>

Get the caller’s Actor ID

  • Some(caller_id): Called by another Actor
  • None: System internal call (e.g., lifecycle hooks)
Source

fn request_id(&self) -> &str

Get the unique request ID

A new request_id is generated for each RPC call, used to match requests and responses.

Source

fn call<'life0, 'life1, 'async_trait, R>( &'life0 self, target: &'life1 Dest, request: R, ) -> Pin<Box<dyn Future<Output = ActorResult<R::Response>> + Send + 'async_trait>>
where R: 'async_trait + RpcRequest, Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Send a type-safe RPC request and wait for response

This is the primary way to call other Actors, providing full type safety guarantees.

§Type Inference

Response type is automatically inferred from R::Response, no manual annotation needed:

let request = EchoRequest { message: "hello".to_string() };
let response: EchoResponse = ctx.call(&target, request).await?;
//              ^^^^^^^^^^^^ Inferred from EchoRequest::Response
§Error Handling
  • ProtocolError::TransportError: Network transport failure
  • ProtocolError::Actr(DecodeFailure): Response decode failure
  • ProtocolError::Actr(UnknownRoute): Route does not exist
  • Errors returned by remote Actor’s business logic
§Parameters
  • target: Target destination (Dest::Shell for local, Dest::Actor(id) for remote)
  • request: Request message implementing RpcRequest trait
§Returns

Returns response message of type R::Response

Source

fn tell<'life0, 'life1, 'async_trait, R>( &'life0 self, target: &'life1 Dest, message: R, ) -> Pin<Box<dyn Future<Output = ActorResult<()>> + Send + 'async_trait>>
where R: 'async_trait + RpcRequest, Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Send a type-safe one-way message (no response expected)

Used for sending notifications, events, etc. that do not require a response.

§Semantics
  • Fire-and-forget: Does not wait for response after sending
  • No delivery guarantee: Message may be lost if target is unreachable
  • Low latency: Does not block waiting for response
§Parameters
  • target: Target destination (Dest::Shell for local, Dest::Actor(id) for remote)
  • message: Message implementing RpcRequest trait
Source

fn register_stream<'life0, 'async_trait, F>( &'life0 self, stream_id: String, callback: F, ) -> Pin<Box<dyn Future<Output = ActorResult<()>> + Send + 'async_trait>>
where F: Fn(DataStream, ActrId) -> BoxFuture<'static, ActorResult<()>> + Send + Sync + 'static + 'async_trait, Self: 'async_trait, 'life0: 'async_trait,

Register a DataStream callback for a specific stream

When a DataStream with matching stream_id arrives, the registered callback will be invoked. Callbacks are executed concurrently and do not block other streams.

§Parameters
  • stream_id: Stream identifier (must be globally unique)
  • callback: Handler function that receives (DataStream, sender ActrId)
§Example
ctx.register_stream("log-stream", |chunk, sender| {
    Box::pin(async move {
        println!("Received chunk {} from {:?}", chunk.sequence, sender);
        Ok(())
    })
}).await?;
Source

fn unregister_stream<'life0, 'life1, 'async_trait>( &'life0 self, stream_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = ActorResult<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Unregister a DataStream callback

§Parameters
  • stream_id: Stream identifier to unregister
Source

fn send_data_stream<'life0, 'life1, 'async_trait>( &'life0 self, target: &'life1 Dest, chunk: DataStream, ) -> Pin<Box<dyn Future<Output = ActorResult<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Send a DataStream to a destination

DataStreams are sent via Fast Path with configurable QoS based on PayloadType.

§Parameters
  • target: Target destination
  • chunk: DataStream to send
Source

fn discover_route_candidate<'life0, 'life1, 'async_trait>( &'life0 self, target_type: &'life1 ActrType, ) -> Pin<Box<dyn Future<Output = ActorResult<ActrId>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Discover a remote Actor of the specified type via the signaling server.

Returns a route candidate or an error if none are available. Concrete selection strategy is decided by the Context implementation.

Source

fn register_media_track<'life0, 'async_trait, F>( &'life0 self, track_id: String, callback: F, ) -> Pin<Box<dyn Future<Output = ActorResult<()>> + Send + 'async_trait>>
where F: Fn(MediaSample, ActrId) -> BoxFuture<'static, ActorResult<()>> + Send + Sync + 'static + 'async_trait, Self: 'async_trait, 'life0: 'async_trait,

Register a WebRTC native media track callback

When media samples arrive on the specified track, the registered callback will be invoked. Uses WebRTC native RTCTrackRemote, no protobuf serialization overhead.

§Parameters
  • track_id: Media track identifier (must match WebRTC track ID in SDP)
  • callback: Handler function that receives native media samples
§Example
use actr_framework::MediaSample;

ctx.register_media_track("video-track-1", |sample, sender| {
    Box::pin(async move {
        // Decode and render video frame (native RTP payload)
        println!("Received {} bytes at timestamp {}",
                 sample.data.len(), sample.timestamp);
        decoder.decode(&sample.data).await?;
        Ok(())
    })
}).await?;
§Architecture Note

MediaTrack uses WebRTC native RTP channels (RTCTrackRemote), NOT DataChannel. This provides:

  • Zero protobuf serialization overhead
  • Native RTP header information (timestamp, SSRC, etc.)
  • Optimal latency (~1-2ms lower than DataChannel)
Source

fn unregister_media_track<'life0, 'life1, 'async_trait>( &'life0 self, track_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = ActorResult<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Unregister a media track callback

§Parameters
  • track_id: Media track identifier to unregister
Source

fn send_media_sample<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, target: &'life1 Dest, track_id: &'life2 str, sample: MediaSample, ) -> Pin<Box<dyn Future<Output = ActorResult<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Send media samples via WebRTC native track

Sends raw media samples through WebRTC RTCRtpSender (native RTP). This is much more efficient than sending through DataChannel.

§Parameters
  • target: Target destination
  • track_id: Track identifier
  • sample: Media sample to send
§Example
use actr_framework::{MediaSample, MediaType};

let sample = MediaSample {
    data: encoded_frame.into(),
    timestamp: rtp_timestamp,
    codec: "H264".to_string(),
    media_type: MediaType::Video,
};

ctx.send_media_sample(&target, "video-track-1", sample).await?;

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§