使用Akka的Actors进行异步消息处理

时间:2017-02-21 07:06:33

标签: scala akka actor

在我的项目中,我正在使用Akka的演员。根据定义,Actors是线程安全的,这意味着在Actor的 receive 方法中

def receive = {
    case msg =>
        // some logic here
}

一次只有一个线程处理注释的代码段。但是,当这段代码异步时,事情开始变得更加复杂:

def receive = {
    case msg =>
        Future {
            // some logic here
        }
}

如果我理解正确的话,在这种情况下,只有Future构造才会被同步,而不是逻辑里面未来。

当然,我可以阻止未来:

def receive = {
    case msg =>
        val future = Future {
            // some logic here
        }
        Await.result(future, 10.seconds)
}

解决了这个问题,但我认为我们都应该同意这不是一个可以接受的解决方案。

所以这是我的问题:在异步计算没有阻止Scala的期货的情况下,如何保留参与者的线程安全特性?

3 个答案:

答案 0 :(得分:6)

  

如果有的话,我如何保留演员的线程安全性   没有块Scalas Future

的异步计算

这个假设只有在你修改Future里面的演员的内部状态时才会出现,这似乎是一个设计气味。仅使用未来进行计算,方法是使用pipeTo创建数据的副本并将管道计算结果传递给actor。一旦演员收到计算结果,你就可以安全地对其进行操作:

import akka.pattern.pipe

case class ComputationResult(s: String)

def receive = {
  case ComputationResult(s) => // modify internal state here
  case msg =>
    Future {
       // Compute here, don't modify state
       ComputationResult("finished computing")
    }.pipeTo(self)
}

答案 1 :(得分:0)

我认为您需要首先“解析”db查询,然后使用结果返回新的SELECT mdkamvp.mdkamda_sid, (SELECT DISTINCT first_value(subject) over (partition BY subject ORDER BY dateto DESC) FROM mdkndlst WHERE subject IS NOT NULL ) naktion, mdkamvp.rowid row_id FROM springv2.mdkamvp ORDER BY mdkamvp.indstatus 。如果db查询返回Future,那么您可以使用Future[A]flatMap进行操作并返回新的A

中的某些内容
Future

答案 2 :(得分:0)

这里最简单的解决方案是将actor转变为状态机(使用AkkaFSM)并执行以下操作:

  • 为mongoDB请求分发未来。
  • 使用对您自己的演员的引用来与您的演员交流
  • 从未来回复消息。

取决于上下文,您可能需要做更多工作才能获得正确的响应。

但是这样做的好处是你可以使用actor状态处理消息,并且可以随心所欲地改变actor状态。