Actor层次结构

Riker中的Actor形成一个层次结构,每个actor都可以通过路径寻址。 actor在层次结构中的位置由其父级的位置决定。 让我们看一下actorsystem启动后的actor层次结构:

  1. my-app
  2. └─ user
  3. └─ system
  4. └─ logger
  5. └─ event_stream
  6. └─ dead_letters
  7. └─ event_store
  8. └─ default_stream
  9. └─ io_manager
  10. └─ tcp
  11. └─ dl_logger
  12. └─ temp

我们可以看到,如果没有开始任何 actor,我们已经有很多 actor在跑。 在层次结构的基础上是我们的应用程序根,它具有在system启动时提供的名称:ActorSystem :: new(“my-app”)。

然后是三个根 actorusersystemtemp actor。 也许最重要的是user,因为作为应用程序的一部分创建的大多数 actor都是在这个分支中创建的。

如果我们使用system.actor_of(props,“my-actor”)启动一个actor,我们可以在user下看到它添加:

  1. my-app
  2. └─ user
  3. └─ my-actor <-- our new actor is added
  4. └─ system
  5. └─ logger
  6. └─ event_stream
  7. └─ dead_letters
  8. └─ event_store
  9. └─ default_stream
  10. └─ io_manager
  11. └─ tcp
  12. └─ dl_logger
  13. └─ temp

在这种情况下,新创建的my-actor有一个/ user / my-actor路径。 由于它是在ActorSystem上使用actor_of启动的,因此它被认为是顶级actor

让我们看看当另一个actor启动时层次结构如何变化,这次是使用Context.actor_of/ user / my-actorreceive方法中。

  1. impl Actor for MyActor {
  2. type Msg = String;
  3. fn receive(&mut self,
  4. ctx: &Context<Self::Msg>,
  5. msg: Self::Msg,
  6. sender: ActorRef<Self::Msg>) {
  7. ctx.actor_of(MyActor::props(), "my-child").unwrap();
  8. }
  9. }

这里MyActor将启动另一个actor,它也是MyActor的一个实例。

  1. my-app
  2. └─ user
  3. └─ my-actor
  4. └─ my-child <-- our new actor is added
  5. └─ system
  6. └─ logger
  7. └─ event_stream
  8. └─ dead_letters
  9. └─ event_store
  10. └─ default_stream
  11. └─ io_manager
  12. └─ tcp
  13. └─ dl_logger
  14. └─ temp

由于新 actor是使用my-actor的上下文开始的,因此它会作为my-actor的子节点添加到层次结构中。 我子Actor的路径变为/ user / my-actor / my-child

让我们继续下一节,在构建弹性应用程序时,明确了 actor层次结构实现监督的重要性。