【问题标题】:Akka Ask Pattern with many types of responsesAkka Ask Pattern 具有多种类型的响应
【发布时间】:2017-09-25 10:32:56
【问题描述】:

我正在编写一个必须与使用 Akka 实现的库进行交互的程序。具体来说,这个库将 Actor 公开为端点。

据我所知,正如 Applied Akka Pattern 一书中所解释的那样,从外部与 Actor 系统交互的最佳方式是使用 Ask Pattern

我必须使用的库公开了一个接受Create 消息的演员Main。作为对该消息的响应,它可以向调用者发送两条不同的消息,CreateAckCreateNack(error)

我使用的代码或多或少如下。

implicit val timeout = Timeout(5 seconds)
def create() = (mainActor ? Create).mapTo[???]

问题显然是我不知道我必须在mapTo函数中使用哪种类型,而不是???

我是否使用了正确的方法?是否有任何其他有用的模式可以从不使用 Actors 的外部程序访问 Actor System?

【问题讨论】:

    标签: scala akka


    【解决方案1】:

    一般来说,最好让 Actors 在 Actors 之间进行交谈,然后您会收到一个响应 - 很简单。

    如果您确实必须将它们与“外部”集成,那么询问模式确实很好。请注意,如果您在 Actor 内部执行此操作,这可能不是最好的方法。

    如果我建议有许多不相关的响应类型:

    (1) 制作这样的普通类型;这可以很简单:

    sealed trait CreationResponse
    final case object CreatedThing extends CreationResponse
    final case class FailedCreationOfThing(t: Throwable) extends CreationResponse
    final case class SomethingElse...(...) extends CreationResponse
    

    这使得协议易于理解和跟踪。我推荐这个,因为它很明确,有助于理解发生了什么。

    (2) 顺便说一下,对于完全不相关的类型,只需在未来收集就可以了,而无需执行mapTo

    val res: Future[...] = (bob ? CreateThing) collect { 
      case t: ThatWorked => t // or transform it
      case nope: Nope    => nope // or transform it to a different value
    }
    

    如果结果tnope 有一个共同的超类型,那么这将在类型方面工作得很好,那么该类型将是结果Future 中的...。如果一条消息返回并且不匹配任何情况,这将是一个匹配错误;例如,您可以添加一个case _ => whatever,或者它会指向一个编程错误。

    【讨论】:

    • 非常感谢。非常好的和完整的解释。关于你的句子这使得协议易于理解和跟踪,他们真正的程序使用易于理解的名称:)
    【解决方案2】:

    查看CreateAckCreateNack(error) 是否继承自任何类型的类或对象。如果是这种情况,您可以使用.mapTo[CreateResultType] 中的父类或对象。

    另一种解决方案是使用.mapTo[Any] 并使用match case 来查找结果类型。

    【讨论】:

      猜你喜欢
      • 2017-03-20
      • 2022-01-13
      • 2020-05-13
      • 1970-01-01
      • 1970-01-01
      • 2020-04-06
      • 2019-06-10
      • 1970-01-01
      • 2021-11-26
      相关资源
      最近更新 更多