Address
Actor通过交换消息进行通信。发送者可以选择等待回应。actor不能直接引用,只能通过他们的Address引用。
有几种方法可以获得Actor的Address。 Actor trait提供启动actor的两个辅助方法。两者都返回已启动actor的Address。
这是一个Actors::tart()方法用法的例子。在这个例子中,MyActor actor是异步的,并且在与调用者相同的线程中启动。
extern crate actix;use actix::prelude::*;struct MyActor;impl Actor for MyActor {type Context = Context<Self>;}fn main() {System::new("test");let addr = MyActor.start();}
异步actor可以从Context对象获取其地址。Context需要实现AsyncContext trait。 AsyncContext::address()提供了actor的addres。
extern crate actix;use actix::prelude::*;struct MyActor;impl Actor for MyActor {type Context = Context<Self>;fn started(&mut self, ctx: &mut Context<Self>) {let addr = ctx.address();}}fn main() {}
Mailbox
所有消息首先转到actor的mailbox,然后是actor的执行上下文调用特定的消息处理。mailbox通常是bounded的。容量是特定于上下文实现。对于Context类型,容量设置为默认情况下有16条消息,可以增加
Context:: set_mailbox_capacity()。
Message
为了能够处理特定消息, actor必须提供此消息的Handler<M>实现。所有消息都是静态类型的。消息可以以异步方式处理。actor可以产生其他actor或添加future或 streams到执行上下文。 actortrait提供了几种方法允许控制actor的生命周期。
要向actor发送消息,需要使用Addr对象。 Addr提供了几个发送消息的方式。
addr::do_send(M)- 这个方法忽略了actor的mailbox容量无条件地发送消息到邮箱。此方法不返回消息处理结果,如果actor不在,则无声地失败。Addr :: try_send(M)- 此方法尝试立即发送消息。如果mailbox已满或关闭(actor已死),此方法返回一个SendError。Addr :: send(M)- 此消息返回一个解析为future对象的结果,如果消息处理过程返回的Future对象被消毁,那么消息被取消。
Recipient
Recipient是address的特别版本,仅支持一种类型的message。它可以用于需要将消息发送给不同类型的actor的情况。可以使用Addr :: recipient()从address创建recipient对象。
例如,recipient可以用于订阅系统。在以下示例中ProcessSignals actor向所有订阅者发送Signal消息。订户可以是任何实现Handler <Signal> trait 的actor。
#[macro_use] extern crate actix;use actix::prelude::*;#[derive(Message)]struct Signal(usize);/// Subscribe to process signals.#[derive(Message)]struct Subscribe(pub Recipient<Signal>);/// Actor that provides signal subscriptionsstruct ProcessSignals {subscribers: Vec<Recipient<Signal>>,}impl Actor for ProcessSignals {type Context = Context<Self>;}impl ProcessSignals {/// Send signal to all subscribersfn send_signal(&mut self, sig: usize) {for subscr in &self.subscribers {subscr.do_send(Signal(sig));}}}/// Subscribe to signalsimpl Handler<Subscribe> for ProcessSignals {type Result = ();fn handle(&mut self, msg: Subscribe, _: &mut Self::Context) {self.subscribers.push(msg.0);}}fn main() {}
