繁体   English   中英

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

[英]Akka Actor - pipeTo - Is it inadvisable to use values from the received message in the piped reply?

我正在使用pipeTo模式在Actor中处理Future ,看来工作正常。

在下面的示例中,我在UserProxyActor下方进行了UserProxyActorUserActivityActor询问了Get(userId)消息。

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

  1. map调用中可以使用userId还是将其“关闭”?
  2. 这会因为问号模式会阻塞而起作用吗?
  3. 有没有更好的方式做到这一点,而我还没有遇到过?
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还是将其“关闭”?

Get应该是一成不变的,如果是userId将可用。

这会因为问号模式会阻塞而起作用吗?

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

有没有更好的方式做到这一点,而我还没有遇到过?

如果repository.queryHistoricalActivities(userId)没有阻止调用,则看起来不错。

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

我唯一要提及的是,我个人不喜欢在演员之间进行交流时使用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秒钟,否则会收到故障,它可能无限期地等待)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM