Akka Actor-pipeTo-在管道答复中使用接收到的消息中的值是否不明智?

时间:2019-05-03 12:11:00

标签: scala akka

我正在以pipeTo模式处理Actor中的UserProxyActor,似乎正常。

在这个示例中,我在UserActivityActor下面模拟了Get(userId)并发出map消息。

我想在响应中包括Get消息的参数,以便接收方具有处理消息所需的一切。例如,将活动与相关的userId插入数据库中。

  1. class UserActivityActor(repository: UserActivityRepository) extends Actor { import akka.pattern.pipe import UserActivityActor._ implicit val ec: ExecutionContext = context.dispatcher def receive = { case Get(userId) => // user's historical activities are retrieved // via the separate repository repository.queryHistoricalActivities(userId) .map(a => UserActivityReceived(userId, a)) // wrap the completed future value in a message .recover{case ex => RepoFailure(ex.getMessage)} // wrap failure in a local message type .pipeTo(sender()) class UserProxyActor(userActivities: ActorRef) extends Actor { import UserProxyActor._ import akka.pattern.{ ask, pipe } implicit val ec: ExecutionContext = context.dispatcher implicit val timeout = Timeout(5 seconds) def receive = { case GetUserActivities(user) => (userActivities ? UserActivityActor.Get(user)) .pipeTo(sender()) } } 调用中是否提供了userId或它被“关闭”了?
  2. 这是行得通的,因为询问模式将被阻止吗?
  3. 有没有更好的方法可以做到这一点?
/etc/passwd

2 个答案:

答案 0 :(得分:1)

  

地图调用中是否提供了userId或它被“封闭”了?

如果是Get,则

userId应该是不变的。

  

这是行得通的,因为询问模式将被阻止吗?

演员收到一条Get消息,创建一个Future,然后处理另一条消息。完全没有阻塞。直到完成Future或发生超时,Ask's Future才完成。

  

有没有更好的方法可以做到这一点?

如果repository.queryHistoricalActivities(userId)没有阻止通话,效果很好。

答案 1 :(得分:0)

我认为您所做的没有任何问题。

我唯一要提及的是,我个人不喜欢在演员之间进行交流时使用ask(请记住,这在很大程度上是个人喜好),所以我会做以下事情:

class UserActivityActor(repository: UserActivityRepository) extends Actor {
  import akka.pattern.pipe
  import UserActivityActor._
  implicit val ec: ExecutionContext = context.dispatcher

  def receive = {
    case Get(userId) =>
      // user's historical activities are retrieved
      // via the separate repository
      repository.queryHistoricalActivities(userId)
        .map(a => UserActivityReceived(userId, a))      // wrap the completed future value in a message
        .recover{case ex => RepoFailure(ex.getMessage)} // wrap failure in a local message type
        .pipeTo(sender())


class UserProxyActor(userActivities: ActorRef) extends Actor {
  import UserProxyActor._

  def receive = {
    case GetUserActivities(user, sender()) =>
      userActivities.forward(UserActivityActor.Get(user))
  }
}

但是,这确实消除了超时行为(在您的原始实现中,发出请求的actor在我的系统中最多等待5秒钟,否则会无限期等待)。