我正在尝试在Akka/Scala中编写一个调用HTTP REST API的演员,并将结果发回给主叫演员。 API可能会返回必须首先转换为内部供应商中性格式的结果的集合/向量,以便将来可以更改供应商,而无需对代码进行太多的更改。大部分的代码工作,但我不知道如何解压缩并发送内部向量。从演员返回实际结果而不是承诺/未来
这是我拥有的代码,它会将Promise
返回给调用actor。我想回到的是,获取最终的map
操作所创建的实际载体:
class RESTActor extends Actor with ActorLogging with JsonSupport {
final implicit val materializer: ActorMaterializer = ActorMaterializer(ActorMaterializerSettings(context.system))
val http = Http(context.system)
import akka.pattern.pipe
import context.dispatcher
override def receive: Receive = {
case query: String => {
val requester = sender
var uri = Uri(Settings.autoCompleteURL).withQuery(Query(Map("query" -> query)))
sender! http
.singleRequest(HttpRequest(HttpMethods.GET, uri = uri))
.flatMap(response =>
response.status match {
case status if status.isSuccess() => Unmarshal(response.entity).to[VendorResponse].map(_.result.map(x => VendorNeutralResponse(x.id, x.field)))
case _ => response.entity.toStrict(5.seconds).map { entity =>
val body = entity.data.decodeString("UTF-8")
log.warning(errorMessage(response, body))
Left(errorMessage(response, body))
}
})
}
}
调用演员:
pathPrefix("search") {
get {
parameter("query") { query =>
{
complete(restActor.ask(query)) //Doesn't work as the reply is a promise
}
}
}
}
如何更改上面的代码中RESTActor发送实际结果而不是未来或承诺?
编辑:根据我自己的研究和建议更改代码之后@米哈尔和@西里尔 - corpet,下面的代码工作:
pathPrefix("search") {
get {
parameter("query") { query =>
{
onComplete(gisRouter.ask(query)) {
case Success(resp: Future[Vector[VendorNeutralResponse]]) => {
resp.map(println)
complete("ok")
}
case Failure(e) => complete(e.toString)
}
}
}
}
}
好像我仍然得到一个future
作为我的演员的回应。我如何让演员回应实际数据而不是Future
?
嗨..代码没有帮助。我仍然需要在onComplete中解开未来。请参阅更新/编辑。 – MojoJojo
@MojoJojo对答案的编辑建议你将'Future'传送给发件人,而不是回复Future作为回复的一部分 – dk14
@ dk14编辑完成是因为此评论... –