演员好习惯?

时间:2013-12-11 06:32:27

标签: scala coding-style akka

我有一个使用scala运行的akka​​ actor系统。现在我需要并行配置多个设备,因此我有一个Manager actor来管理所有这些配置任务。要实际配置它们,他将为每个配置生成一个Worker actor,以便它们可以并发或并行运行。现在Worker演员不需要在配置期间从经理那里接收消息,他只需要做他的事情,然后报告他已经回到Manager

现在问题是我是否在ActorRef的构造函数中传递了Manager的{​​{1}}或者我是否创建了它,然后向它发送了一条消息,如{{ 1}}然后它会在完成后回复Worker?是否有一个约定如何做到这一点或被认为是一种良好的做法?

编辑:正如Vladimir Matveev提醒我的那样,对Do(action: => Unit)的引用不是问题,因为sender中的层次结构已经知道了它。这只留下了如何将作品传递给Manager的问题。

1 个答案:

答案 0 :(得分:2)

你是对的,工作应该通过消息传递给工人。因为这是与演员沟通的最安全的方式。它还使您能够在演员面前使用调度程序将分配的工作分割为多个工作人员。

为清楚起见,这是一个简短的例子:

import akka.actor.Actor
import akka.actor.Props

case class Start()
case class Finished()
case class Do(action: () => Unit)

class Manager extends Actor {

  override def preStart() =
    self ! Start()

  def receive = {
    case Start() =>
      val workers = context.actorOf(
        Props[Worker].withRouter(RoundRobinRouter(nrOfInstances = 5)))
      context.system.scheduler.schedule(5 seconds, 5 seconds, workers, Do(() => 1 * 1))

    case Finished() =>
      println("A worker finished work.")
  }
}

class Worker extends Actor {
  def receive = {
    case Do(f) =>
      f()
      sender ! Finished()
  }
}

在经理开始之后,它将创建5名工作人员并每隔5秒向他们发送一些工作。工人将完成工作并在完成后报告。您可以使用sender(始终向工作的发布者报告)或context.parent(始终向经理报告)报告已完成的工作。