J'essaye d'écrire un acteur dans Akka/Scala qui appelle une API HTTP REST et renvoie le résultat à l'acteur appelant. L'API peut renvoyer une collection/un vecteur de résultats qui doit d'abord être converti en un format interne fournisseur neutre afin que le fournisseur puisse être modifié à l'avenir sans beaucoup de changements requis sur notre code. La plupart du code fonctionne mais je ne suis pas sûr de savoir comment décompresser et envoyer le vecteur interne.Retour résultat réel d'un acteur au lieu de promesse/avenir
C'est le code que j'ai et il renvoie un Promise
à l'acteur invoquant. Ce que je voudrais revenir est le vecteur réelle qui est créé dans l'opération map
finale:
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))
}
})
}
}
L'acteur appelant:
pathPrefix("search") {
get {
parameter("query") { query =>
{
complete(restActor.ask(query)) //Doesn't work as the reply is a promise
}
}
}
}
Comment puis-je modifier le code ci-dessus dans le RESTActor à envoyer réelle résultat au lieu d'un avenir ou d'une promesse?
Modifier: Après avoir modifié le code en fonction de mes propres recherches et suggestions de @ Michał et @ cyrille-Corpet, le code suivant fonctionne:
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)
}
}
}
}
}
Il semble que je suis toujours obtenir un future
en réponse de mon acteur. Comment puis-je obtenir l'acteur de répondre avec des données réelles et non un Future
?
Salut..le code n'aide pas. Je dois encore déballer un futur à l'intérieur sur Complet..veuillez vous référer à la mise à jour/Modifier. – MojoJojo
@MojoJojo la modification à la réponse vous suggère de transmettre 'Future' à l'expéditeur au lieu de retourner Future dans le cadre de la réponse – dk14
@ dk14 L'édition a été faite à cause de ce commentaire ... –