DerivedActorRef

Struct DerivedActorRef 

Source
pub struct DerivedActorRef<TFrom> { /* private fields */ }
Expand description

DerivedActorRef wraps an ActorCell to send messages that can be converted into its accepted type using From. DerivedActorRef allows to create isolation between actors by hiding the actual message type.

§Example

// In this example the actor is a ghost kitchen which can accept orders of different types,
// representing multiple virtual restaurants at once. More specifically, it can accept
// pizza or sushi orders.
//
// Derived actor allows to hide the order message accepted by the kitchen actor, therefore
// we can pass the ref to other components without creating a direct dependency on the
// kitchen actor. We can easily replace or split the kitchen actor without affecting
// other components communicating with it.
use ractor::{Actor, ActorProcessingErr, ActorRef, DerivedActorRef, Message};

// First we define order types
struct PizzaOrder {
    topping: String,
}

struct SushiOrder {
    r#type: String,
    quantity: usize,
}

// The order message which is actually sent to the kitchen actor can be either pizza or sushi
enum Order {
    Pizza(PizzaOrder),
    Sushi(SushiOrder),
}

// Implementing conversion methods from different order types to the actual order
impl From<PizzaOrder> for Order {
    fn from(value: PizzaOrder) -> Self {
        Order::Pizza(value)
    }
}

impl TryFrom<Order> for PizzaOrder {
    type Error = String;

    fn try_from(value: Order) -> Result<Self, Self::Error> {
        match value {
            Order::Pizza(order) => Ok(order),
            _ => Err("Order has invalid type".to_string()),
        }
    }
}

impl From<SushiOrder> for Order {
    fn from(value: SushiOrder) -> Self {
        Order::Sushi(value)
    }
}

impl TryFrom<Order> for SushiOrder {
    type Error = String;

    fn try_from(value: Order) -> Result<Self, Self::Error> {
        match value {
            Order::Sushi(order) => Ok(order),
            _ => Err("Order has invalid type".to_string()),
        }
    }
}

#[cfg(feature = "cluster")]
impl Message for Order {
    fn serializable() -> bool {
        false
    }
}

struct Kitchen;

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

    async fn pre_start(
        &self,
        _myself: ActorRef<Self::Msg>,
        _: (),
    ) -> Result<Self::State, ActorProcessingErr> {
        Ok(())
    }

    async fn handle(
        &self,
        _myself: ActorRef<Self::Msg>,
        message: Self::Msg,
        _state: &mut Self::State,
    ) -> Result<(), ActorProcessingErr> {
        match message {
            Order::Pizza(order) => {
                println!("Preparing pizza with topping {}", order.topping);
            }
            Order::Sushi(order) => {
                println!(
                    "Preparing {} sushi of type {}",
                    order.quantity, order.r#type
                );
            }
        }
        Ok(())
    }
}

async fn example() {
    let (kitchen_actor_ref, kitchen_actor_handle) = Actor::spawn(None, Kitchen, ()).await.unwrap();
     
    // derived actor ref can be passed to the pizza restaurant actor which accepts pizza orders from delivery apps
    let pizza_restaurant: DerivedActorRef<PizzaOrder> = kitchen_actor_ref.get_derived();
    pizza_restaurant.send_message(PizzaOrder {
        topping: String::from("pepperoni"),
    }).expect("Failed to order pizza");

    // same way, we can also get a derived actor ref which can only accept sushi orders
    let sushi_restaurant: DerivedActorRef<SushiOrder> = kitchen_actor_ref.get_derived();
    sushi_restaurant.send_message(SushiOrder {
        r#type: String::from("sashimi"),
        quantity: 3,
    }).expect("Failed to order sushi");

    kitchen_actor_handle.await.unwrap();
}

Implementations§

Source§

impl<TFrom> DerivedActorRef<TFrom>

Source

pub fn send_message(&self, message: TFrom) -> Result<(), MessagingErr<TFrom>>

Casts the message to the target message type of ActorCell and sends it

  • message - The message to send

Returns [Ok(())] on successful message send, [Err(MessagingErr)] otherwise

Source

pub fn get_cell(&self) -> ActorCell

Retrieve a cloned ActorCell representing this DerivedActorRef

Source§

impl<TMessage> DerivedActorRef<TMessage>
where TMessage: Message,

Source

pub fn cast(&self, msg: TMessage) -> Result<(), MessagingErr<TMessage>>

Alias of cast

Source

pub async fn call<TReply, TMsgBuilder>( &self, msg_builder: TMsgBuilder, timeout_option: Option<Duration>, ) -> Result<CallResult<TReply>, MessagingErr<TMessage>>
where TMsgBuilder: FnOnce(RpcReplyPort<TReply>) -> TMessage, TReply: Send + 'static,

Alias of call

Source§

impl<TMessage> DerivedActorRef<TMessage>
where TMessage: Message,

Add the timing functionality on top of the crate::ActorRef

Source

pub fn send_interval<F>(&self, period: Duration, msg: F) -> JoinHandle<()>
where F: Fn() -> TMessage + Send + 'static,

Alias of send_interval

Source

pub fn send_after<F>( &self, period: Duration, msg: F, ) -> JoinHandle<Result<(), MessagingErr<TMessage>>>
where F: FnOnce() -> TMessage + Send + 'static,

Alias of send_after

Source

pub fn exit_after(&self, period: Duration) -> JoinHandle<()>

Alias of exit_after

Source

pub fn kill_after(&self, period: Duration) -> JoinHandle<()>

Alias of kill_after

Methods from Deref<Target = ActorCell>§

Source

pub fn get_id(&self) -> ActorId

Retrieve the super::Actor’s unique identifier ActorId

Source

pub fn get_name(&self) -> Option<String>

Retrieve the super::Actor’s name

Source

pub fn get_status(&self) -> ActorStatus

Retrieve the current status of an super::Actor

Returns the super::Actor’s current ActorStatus

Link this super::Actor to the provided supervisor

Unlink this super::Actor from the supervisor if it’s currently linked (if self’s supervisor is supervisor)

  • supervisor - The supervisor to unlink this super::Actor from
Source

pub fn kill(&self)

Kill this super::Actor forcefully (terminates async work)

Source

pub async fn kill_and_wait( &self, timeout: Option<Duration>, ) -> Result<(), RactorErr<()>>

Kill this super::Actor forcefully (terminates async work) and wait for the actor shutdown to complete

  • timeout - An optional timeout duration to wait for shutdown to occur

Returns [Ok(())] upon the actor being stopped/shutdown. [Err(RactorErr::Messaging(_))] if the channel is closed or dropped (which may indicate some other process is trying to shutdown this actor) or [Err(RactorErr::Timeout)] if timeout was hit before the actor was successfully shut down (when set)

Source

pub fn stop(&self, reason: Option<String>)

Stop this super::Actor gracefully (stopping message processing)

  • reason - An optional string reason why the stop is occurring
Source

pub async fn stop_and_wait( &self, reason: Option<String>, timeout: Option<Duration>, ) -> Result<(), RactorErr<StopMessage>>

Stop the super::Actor gracefully (stopping messaging processing) and wait for the actor shutdown to complete

  • reason - An optional string reason why the stop is occurring
  • timeout - An optional timeout duration to wait for shutdown to occur

Returns [Ok(())] upon the actor being stopped/shutdown. [Err(RactorErr::Messaging(_))] if the channel is closed or dropped (which may indicate some other process is trying to shutdown this actor) or [Err(RactorErr::Timeout)] if timeout was hit before the actor was successfully shut down (when set)

Source

pub async fn wait(&self, timeout: Option<Duration>) -> Result<(), Timeout>

Wait for the actor to exit, optionally within a timeout

  • timeout: If supplied, the amount of time to wait before returning an error and cancelling the wait future.

IMPORTANT: If the timeout is hit, the actor is still running. You should wait again for its exit.

Source

pub fn send_message<TMessage>( &self, message: TMessage, ) -> Result<(), MessagingErr<TMessage>>
where TMessage: Message,

Send a strongly-typed message, constructing the boxed message on the fly

Note: The type requirement of TActor assures that TMsg is the supported message type for TActor such that we can’t send boxed messages of an unsupported type to the specified actor.

  • message - The message to send

Returns [Ok(())] on successful message send, [Err(MessagingErr)] otherwise

Source

pub fn drain(&self) -> Result<(), MessagingErr<()>>

Drain the actor’s message queue and when finished processing, terminate the actor.

Any messages received after the drain marker but prior to shutdown will be rejected

Source

pub async fn drain_and_wait( &self, timeout: Option<Duration>, ) -> Result<(), RactorErr<()>>

Drain the actor’s message queue and when finished processing, terminate the actor, notifying on this handler that the actor has drained and exited (stopped).

  • timeout: The optional amount of time to wait for the drain to complete.

Any messages received after the drain marker but prior to shutdown will be rejected

Source

pub fn notify_supervisor(&self, evt: SupervisionEvent)

Notify the supervisor and all monitors that a supervision event occurred. Monitors receive a reduced copy of the supervision event which won’t contain the crate::actor::BoxedState and collapses the crate::ActorProcessingErr exception to a String

  • evt - The event to send to this super::Actor’s supervisors
Source

pub fn stop_children(&self, reason: Option<String>)

Stop any children of this actor, not waiting for their exit, and threading the optional reason to all children

  • reason: The stop reason to send to all the children

This swallows and communication errors because if you can’t send a message to the child, it’s dropped the message channel, and is dead/stopped already.

Source

pub fn try_get_supervisor(&self) -> Option<ActorCell>

Tries to retrieve this actor’s supervisor.

Returns None if this actor has no supervisor at the given instance or [Some(ActorCell)] supervisor if one is configured.

Source

pub async fn stop_children_and_wait( &self, reason: Option<String>, timeout: Option<Duration>, )

Stop any children of this actor, and wait for their collective exit, optionally threading the optional reason to all children

  • reason: The stop reason to send to all the children
  • timeout: An optional timeout which is the maximum time to wait for the actor stop operation to complete

This swallows and communication errors because if you can’t send a message to the child, it’s dropped the message channel, and is dead/stopped already.

Source

pub fn drain_children(&self)

Drain any children of this actor, not waiting for their exit

This swallows and communication errors because if you can’t send a message to the child, it’s dropped the message channel, and is dead/stopped already.

Source

pub async fn drain_children_and_wait(&self, timeout: Option<Duration>)

Drain any children of this actor, and wait for their collective exit

  • timeout: An optional timeout which is the maximum time to wait for the actor stop operation to complete
Source

pub fn get_children(&self) -> Vec<ActorCell>

Retrieve the supervised children of this actor (if any)

Returns a Vec of ActorCells which are the children that are presently linked to this actor.

Source

pub fn get_type_id(&self) -> TypeId

Retrieve the TypeId of this ActorCell which can be helpful for quick type-checking.

HOWEVER: Note this is an unstable identifier, and changes between Rust releases and may not be stable over a network call.

Source

pub fn is_message_type_of<TMessage>(&self) -> Option<bool>
where TMessage: Message,

Runtime check the message type of this actor, which only works for local actors, as remote actors send serializable messages, and can’t have their message type runtime checked.

Returns None if the actor is a remote actor, and we cannot perform a runtime message type check. Otherwise [Some(true)] for the correct message type or [Some(false)] for an incorrect type will returned.

Source

pub async fn spawn_linked<T>( &self, name: Option<String>, handler: T, startup_args: <T as Actor>::Arguments, ) -> Result<(ActorRef<<T as Actor>::Msg>, JoinHandle<()>), SpawnErr>
where T: Actor,

Spawn an actor of the given type as a child of this actor, automatically starting the actor. This ActorCell becomes the supervisor of the child actor.

  • name: A name to give the actor. Useful for global referencing or debug printing
  • handler The implementation of Self
  • startup_args: Arguments passed to the pre_start call of the Actor to facilitate startup and initial state creation

Returns a [Ok((ActorRef, JoinHandle<()>))] upon successful start, denoting the actor reference along with the join handle which will complete when the actor terminates. Returns [Err(SpawnErr)] if the actor failed to start

Source

pub async fn spawn_local_linked<T>( &self, name: Option<String>, startup_args: <T as ThreadLocalActor>::Arguments, spawner: ThreadLocalActorSpawner, ) -> Result<(ActorRef<<T as ThreadLocalActor>::Msg>, JoinHandle<()>), SpawnErr>

Spawn an actor of the given type as a thread-local child of this actor, automatically starting the actor. This ActorCell becomes the supervisor of the child actor.

  • name: A name to give the actor. Useful for global referencing or debug printing
  • handler The implementation of Self
  • startup_args: Arguments passed to the pre_start call of the ThreadLocalActor to facilitate startup and initial state creation

Returns a [Ok((ActorRef, JoinHandle<()>))] upon successful start, denoting the actor reference along with the join handle which will complete when the actor terminates. Returns [Err(SpawnErr)] if the actor failed to start

Trait Implementations§

Source§

impl<TFrom> Clone for DerivedActorRef<TFrom>

Source§

fn clone(&self) -> DerivedActorRef<TFrom>

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
Source§

impl<TFrom> Debug for DerivedActorRef<TFrom>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl<TMessage> Deref for DerivedActorRef<TMessage>

Source§

type Target = ActorCell

The resulting type after dereferencing.
Source§

fn deref(&self) -> &<DerivedActorRef<TMessage> as Deref>::Target

Dereferences the value.

Auto Trait Implementations§

§

impl<TFrom> Freeze for DerivedActorRef<TFrom>

§

impl<TFrom> !RefUnwindSafe for DerivedActorRef<TFrom>

§

impl<TFrom> Send for DerivedActorRef<TFrom>

§

impl<TFrom> Sync for DerivedActorRef<TFrom>

§

impl<TFrom> Unpin for DerivedActorRef<TFrom>

§

impl<TFrom> !UnwindSafe for DerivedActorRef<TFrom>

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<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> Message for T
where T: Any + Send + 'static,

Source§

fn from_boxed(m: BoxedMessage) -> Result<Self, BoxedDowncastErr>

Convert a BoxedMessage to this concrete type
Source§

fn box_message(self, pid: &ActorId) -> Result<BoxedMessage, BoxedDowncastErr>

Convert this message to a BoxedMessage
Source§

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

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
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<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
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> OutputMessage for T
where T: Message + Clone,

Source§

impl<T> State for T
where T: Any + Send + 'static,