我正在编写一个程序,必须与使用Akka实现的库进行交互。详细地说,该库将Actor公开为端点。
据我所知,正如书Applied Akka Pattern中所解释的那样,从外部与Actor系统交互的最佳方式是使用Ask Pattern。
我必须使用的库公开了一个接受Main
消息的actor Create
。在回复此消息时,它可以向来电者CreateAck
和CreateNack(error)
发送两条不同的消息。
我正在使用的代码或多或少如下。
implicit val timeout = Timeout(5 seconds)
def create() = (mainActor ? Create).mapTo[???]
问题显然是我不知道我必须在mapTo
函数中使用哪种类型,而不是???
。
我使用正确的方法吗?是否有任何其他有用的模式可以从不使用Actors的外部程序访问Actor系统?
答案 0 :(得分:2)
一般情况下,最好让Actors在Actors之间进行交谈,然后你只需收到回复 - 简单。
如果你确实必须将它们与“外部”整合在一起,那么问题模式确实很好。请注意,如果你在演员里面这样做,这可能不是最好的方法。
如果我建议有许多不相关的回复类型:
(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
}
如果结果t
和nope
具有共同的超类型,那么这种方式可以正常工作,那么该类型将是结果...
中的Future
。如果消息回来并且与任何情况都不匹配则会出现匹配错误;例如,您可以添加case _ => whatever
,或者它会指向编程错误。
答案 1 :(得分:0)
查看CreateAck
或CreateNack(error)
是否从任何类或对象继承。如果是这种情况,您可以使用.mapTo[CreateResultType]
中的父类或对象。
另一种解决方案是使用.mapTo[Any]
并使用match case
查找结果类型。