Module ractor::rpc

source ·
Expand description

Remote procedure calls (RPC) are helpful communication primitives to communicate with actors

There are generally 2 kinds of RPCs, cast and call, and their definition comes from the standard Erlang gen_server. The tl;dr is that cast is an send without waiting on a reply while call is expecting a reply from the actor being communicated with.

§Examples

use ractor::concurrency::Duration;
use ractor::{call, call_t, cast};
use ractor::{Actor, ActorProcessingErr, ActorRef, RpcReplyPort};

struct ExampleActor;

enum ExampleMessage {
    Cast,
    Call(RpcReplyPort<String>),
}

#[cfg(feature = "cluster")]
impl ractor::Message for ExampleMessage {}

#[cfg_attr(feature = "async-trait", ractor::async_trait)]
impl Actor for ExampleActor {
    type Msg = ExampleMessage;
    type State = ();
    type Arguments = ();

    async fn pre_start(
        &self,
        _myself: ActorRef<Self::Msg>,
        _args: Self::Arguments,
    ) -> Result<Self::State, ActorProcessingErr> {
        println!("Starting");
        Ok(())
    }

    async fn handle(
        &self,
        _myself: ActorRef<Self::Msg>,
        message: Self::Msg,
        _state: &mut Self::State,
    ) -> Result<(), ActorProcessingErr> {
        match message {
            ExampleMessage::Cast => println!("Cast message"),
            ExampleMessage::Call(reply) => {
                println!("Call message");
                let _ = reply.send("a reply".to_string());
            }
        }
        Ok(())
    }
}

#[tokio::main]
async fn main() {
    let (actor, handle) = Actor::spawn(None, ExampleActor, ())
        .await
        .expect("Failed to startup dummy actor");

    // send a 1-way message (equivalent patterns)
    actor
        .cast(ExampleMessage::Cast)
        .expect("Failed to send message");
    cast!(actor, ExampleMessage::Cast).expect("Failed to send message");

    // Send a message to the actor, with an associated reply channel,
    // and wait for the reply from the actor (optionally up to a timeout)
    let _result = actor
        .call(ExampleMessage::Call, Some(Duration::from_millis(100)))
        .await
        .expect("Failed to call actor");
    let _result = call!(actor, ExampleMessage::Call).expect("Failed to call actor");
    let _result =
        call_t!(actor, ExampleMessage::Call, 100).expect("Failed to call actor with timeout");

    // wait for actor exit
    actor.stop(None);
    handle.await.unwrap();
}

Re-exports§

Modules§

  • This module contains the remote procedure call’s CallResult structure and supported operations

Functions§

  • Sends an asynchronous request to the specified actor, building a one-time use reply channel and awaiting the result with the specified timeout
  • Send a message asynchronously to another actor, waiting in a new task for the reply and then forwarding the reply to a followup-actor. If this CallResult from the first actor is not success, the forward is not sent.
  • Sends an asynchronous request to the specified actor, ignoring if the actor is alive or healthy and simply returns immediately
  • Sends an asynchronous request to the specified actors, building a one-time use reply channel for each actor and awaiting the results with the specified timeout