Akka Actors的异步初始化

10

我正在尝试找到一个适当的模式来异步初始化Actor,以便我可以查找它所需的相关 ActorRef 。 我想避免使用 ActorSelection ,因为它

  • 指向的演员数量不确定,
  • 对于许多tell而言其开销过大。

查看Actor LifeCycle ,似乎一切都是同步的,直到消息循环开始,包括 preStart ,等等,这使我认为我只有两种选择:

使用带有Future [ActorRef] 签名的工厂方法

解决构造Actor所需的所有依赖项,并通过Props 异步传入。

这种方法的主要问题在于您无法使用此工厂在另一个Actor内部构造Actor,因为它会遇到同样的问题,即它是层层调用的,异步连接所有Actor及其依赖关系的层次结构。

使用become stash 转换Actor

该Actor通过actorOf 创建,立即生成一个ActorRef ,但它从一个初始化状态开始,解决其依赖关系并在此过程中stash传入的消息,最终become运行状态并进行unstashAll 操作。

尽管我的依赖项将全部为var而不是val,但这感觉更像是Actor的惯用方式。

两种方法都需要很多开销,这让我想知道这些是否是最佳选项,或者我是否还没有在文档中找到适当的模式。

1个回答

8
使用become时,依赖项无需是变量。
val initializing: Actor.Receive = {
  case Dependencies(d1, d2) => context.become(working(d1, d2))
}

def working(d1: Dependency, d2: Dependency): Actor.Receive = {
  case msg => d1.fetch(...) // whatever
}

def receive = initializing

此外,actorFor已经被弃用且不会创建一个actor。

修改了actorFor的使用,原来是个打字错误。become看起来确实是最好的解决方式。仍然无法相信没有异步版本的Props示例。 - Arne Claassen
我已经按照您的建议为基于become/stash的初始化阶段创建了一个特质,并具备不可变运行状态:https://gist.github.com/sdether/15bc96e27ed965bd89c3 - Arne Claassen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接