需要使用Akka

时间:2016-05-02 13:48:24

标签: akka actor

我有一个正在编排数据库更新的actor。我需要确保每个操作仅在前一个操作完成后执行。 这是因为操作B将重用操作A的结果。

这是我为演员写的代码。

class DbUpdateActor(databaseOperations: DBProvider) extends Actor {

  implicit val ec:ExecutionContext = context.system.dispatcher

  def receive: Receive = {

    case newInfo : UpdateDb =>

      val future = Future {
            // gets the current situation from DB 
            val status = databaseOperations.getSituation()
            // do db update
            databaseOperations.save(something)
      }

      future onComplete {
        case Success(result: List[Int]) =>
            //
        case Failure(err: Throwable) =>
            //
      }
  }
}

该代码适用于单个操作。如果我触发两个更新,那么第二个更新将异步执行,以便在第一个更新完成之前启动。

我正在阅读有关不同类型邮箱的信息,不确定是否有其他类型的邮箱会有所帮助。

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

您可以探索的一个选项是删除Future并允许阻止db代码在actor中运行。然后,使用单独的调度程序(可能是PinnedDispatcher)从主actor系统的调度程序中解除阻塞代码,为其提供自己的运行线程。通过阻塞正文并删除Future,您将确保正确顺序执行actor的邮箱。这项改变的粗略草图如下:

object DbUpdateActor{
  def props(databaseOperations:DBProvider) =
    Props(classOf[DbUpdateActor], databaseOperations).
      withDispatcher("db-update-dispatcher")
}

class DbUpdateActor(databaseOperations: DBProvider) extends Actor {
  def receive: Receive = {

    case newInfo : UpdateDb =>
      val status = databaseOperations.getSituation()
      databaseOperations.save(something)
  }
}

然后,只要您在actor系统配置中配置了以下调度程序:

db-update-dispatcher {
  executor = "thread-pool-executor"
  type = PinnedDispatcher
}

你启动了db update actor就像这样:

val updater = system.actorOf(DbUpdateActor.props(databaseOperations))

然后你应该全部设置这个演员,以不会对主调度员的吞吐量产生负面影响的方式运行阻塞代码。

答案 1 :(得分:0)

这个怎么样:在孩子中开始手术A;当孩子完成时,它会向父母发送一条消息,说明已完成。然后,您可以在现有孩子或新孩子中开始操作B.