如何与其包装器一起构造一个actor?

blu*_*e10 5 scala akka

我正在尝试写一个叫做ActorManager另一个演员叫的演员RealActor.我们的想法是ActorManager可以处理所有进出的消息RealActor,允许添加其他逻辑,如过滤或缓冲.外部世界应该RealActor通过其经理与唯一的交流,就像在现实世界中一样.

初稿看起来像这样:

class ActorManager(realActor: ActorRef) extends Actor {
  def receive = {
    case _ => { /* pre-process messages */ }
  }
}

class RealActor(actorManager: ActorRef) extends Actor {
  def receive = {
    case _ => { /* actual business logic */ }
  }
}
Run Code Online (Sandbox Code Playgroud)

然而,这提出了如何一次构建两个actor,或者更具体地说如何定义Props两个actor的循环依赖关系的问题.我不确定定义时一般lazy val模式是否适用Props.

我还想避免首先构建两个中的一个,并引入一个显式Register协议来连接它们.

blu*_*e10 6

通过使用actor层次结构而不是普通的actor兄弟,可以更好地解决这种情况.由于这里的主要目的是隐藏RealActor外部世界,因此更有意义的是它ActorRef由外部包裹/拥有ActorManager.

这意味着RealActor必须在范围内创建引用ActorManager.这可以通过传递父ActorRef => Props函数来实现,允许创建子actor:

// Parent
class ActorManager(getRealActorProps: ActorRef => Props) extends Actor {
  val realActor = context.actorOf(getRealActorProps(self))
  def receive = {
    case _ => { /* pre-process messages */ }
  }
}

// Child
class RealActor(actorManager: ActorRef) extends Actor {
  def receive = {
    case _ => { /* actual business logic */ }
  }
}

object RealActor {
  def propsActorManager(getRealActorProps: ActorRef => Props) = 
    Props(new ActorManager(getRealActorProps))
  def propsRealActor(actorManager: ActorRef) = 
    Props(new RealActor(actorManager))

  def props() = 
    Props(new ActorManager(actorManager => propsRealActor(actorManager)))
}
Run Code Online (Sandbox Code Playgroud)

请注意,现在甚至可以隐藏RealActor通过提供适当的props定义来包装的事实,该定义ActorManager -> RealActor隐式地构建层次结构.

另请参阅此博客文章,了解为什么平面演员层次结构被视为反模式.