Skip to main content

Module rpc

Module 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::call;
use ractor::call_t;
use ractor::cast;
use ractor::concurrency::Duration;
use ractor::Actor;
use ractor::ActorProcessingErr;
use ractor::ActorRef;
use ractor::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();
}

Modules§

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

Enums§

CallResult
The result from a crate::rpc::call operation

Functions§

call
Sends an asynchronous request to the specified actor, building a one-time use reply channel and awaiting the result with the specified timeout
call_and_forward
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.
cast
Sends an asynchronous request to the specified actor, ignoring if the actor is alive or healthy and simply returns immediately
multi_call
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