Address

Actor通过交换消息进行通信。发送者可以选择等待回应。actor不能直接引用,只能通过他们的Address引用。

有几种方法可以获得ActorAddressActor trait提供启动actor的两个辅助方法。两者都返回已启动actorAddress

这是一个Actors::tart()方法用法的例子。在这个例子中,MyActor actor是异步的,并且在与调用者相同的线程中启动。

  1. extern crate actix;
  2. use actix::prelude::*;
  3. struct MyActor;
  4. impl Actor for MyActor {
  5. type Context = Context<Self>;
  6. }
  7. fn main() {
  8. System::new("test");
  9. let addr = MyActor.start();
  10. }

异步actor可以从Context对象获取其地址。Context需要实现AsyncContext trait。 AsyncContext::address()提供了actor的addres

  1. extern crate actix;
  2. use actix::prelude::*;
  3. struct MyActor;
  4. impl Actor for MyActor {
  5. type Context = Context<Self>;
  6. fn started(&mut self, ctx: &mut Context<Self>) {
  7. let addr = ctx.address();
  8. }
  9. }
  10. fn main() {}

Mailbox

所有消息首先转到actor的mailbox,然后是actor的执行上下文调用特定的消息处理。mailbox通常是bounded的。容量是特定于上下文实现。对于Context类型,容量设置为默认情况下有16条消息,可以增加 Context:: set_mailbox_capacity()

Message

为了能够处理特定消息, actor必须提供此消息的Handler<M>实现。所有消息都是静态类型的。消息可以以异步方式处理。actor可以产生其他actor或添加futurestreams到执行上下文。 actortrait提供了几种方法允许控制actor的生命周期。

要向actor发送消息,需要使用Addr对象。 Addr提供了几个发送消息的方式。

  • addr::do_send(M) - 这个方法忽略了actormailbox容量无条件地发送消息到邮箱。此方法不返回消息处理结果,如果actor不在,则无声地失败。

  • Addr :: try_send(M) - 此方法尝试立即发送消息。如果mailbox已满或关闭(actor已死),此方法返回一个SendError

  • Addr :: send(M) - 此消息返回一个解析为future对象的结果,如果消息处理过程返回的Future对象被消毁,那么消息被取消。

Recipient

Recipientaddress的特别版本,仅支持一种类型的message。它可以用于需要将消息发送给不同类型的actor的情况。可以使用Addr :: recipient()address创建recipient对象。

例如,recipient可以用于订阅系统。在以下示例中ProcessSignals actor向所有订阅者发送Signal消息。订户可以是任何实现Handler <Signal> trait 的actor。

  1. #[macro_use] extern crate actix;
  2. use actix::prelude::*;
  3. #[derive(Message)]
  4. struct Signal(usize);
  5. /// Subscribe to process signals.
  6. #[derive(Message)]
  7. struct Subscribe(pub Recipient<Signal>);
  8. /// Actor that provides signal subscriptions
  9. struct ProcessSignals {
  10. subscribers: Vec<Recipient<Signal>>,
  11. }
  12. impl Actor for ProcessSignals {
  13. type Context = Context<Self>;
  14. }
  15. impl ProcessSignals {
  16. /// Send signal to all subscribers
  17. fn send_signal(&mut self, sig: usize) {
  18. for subscr in &self.subscribers {
  19. subscr.do_send(Signal(sig));
  20. }
  21. }
  22. }
  23. /// Subscribe to signals
  24. impl Handler<Subscribe> for ProcessSignals {
  25. type Result = ();
  26. fn handle(&mut self, msg: Subscribe, _: &mut Self::Context) {
  27. self.subscribers.push(msg.0);
  28. }
  29. }
  30. fn main() {}