Je suis assez nouveau dans le monde Akka et je dois migrer un projet de Spray à Akka-http.En complétant une demande en dehors du contrôleur principal dans Akka-http
En pulvérisation, une route était de type Route = RequestContext ⇒ Unit
. Mais dans akka-http, il s'agit du type Route = RequestContext ⇒ Future[RouteResult]
. Donc, en pulvérisation, nous traitons et complétons souvent nos demandes à travers une chaîne d'acteurs (en dehors du contrôleur principal) en utilisant seulement le feu et l'oubli, donc nous n'avons pas eu à "demander" et la performance était excellente . Maintenant, nous devons utiliser "demander" chaque fois que nous passons la demande à un autre acteur (corrigez-moi si je me trompe)
J'ai beaucoup cherché et j'ai trouvé quelques options dont je ne suis pas sûr si elles me satisfont pleinement (nécessité de compléter une requête dans un autre acteur sans avoir à le renvoyer au contrôleur). C'est donc là que vous pourriez me aider :)
Option 1: Utilisation onSuccess
/onComplete
N'utilisant ce bloc mon contrôleur principal de recevoir plus de demandes?
Option 2: Utilisation Future
s et en utilisant RouteResult.Complete
J'ai trouvé l'exemple suivant à How to complete a request in another actor when using akka-http:
import akka.actor.{ActorSystem, Actor, Props}
import akka.pattern.ask
import akka.stream.ActorMaterializer
import akka.http.scaladsl.Http
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.{RequestContext, RouteResult}
import scala.concurrent.Future
import akka.http.scaladsl.model.HttpResponse
import akka.util.Timeout
class RequestActor extends Actor {
//business logic - returns empty HttpResponse
def handleRequestMessage(requestContext : RequestContext) =
RouteResult.Complete(new HttpResponse())
override def receive = {
case reqContext : RequestContext =>
sender ! handleRequestMessage(reqContext)
}
}//end class RequestActor
object RouteActorTest extends App {
implicit val as = ActorSystem("RouteActorTest")
implicit val timeout = new Timeout(1000)
val actorRef = as actorOf Props[RequestActor]
def handleRequest(reqContext : RequestContext) : Future[RouteResult] =
ask(actorRef,reqContext).mapTo[RouteResult]
val route = path("") { get(handleRequest) }
//rest of application...
}//end object RouteActorTest
Mais cela passe effectivement la réponse à chaque fois de retour à la précédente Acteur (l'expéditeur) jusqu'à ce qu'il atteigne le contrôleur principal. Une autre chose au sujet de cette option est que dans le code, il est dit:
/**
* The result of handling a request.
*
* As a user you typically don't create RouteResult instances directly.
* Instead, use the methods on the [[RequestContext]] to achieve the desired effect.
*/
Je ne suis pas sûr que ce soit une façon recommandée de le faire.
J'ai essayé d'utiliser requestContext.complete() dans un autre acteur mais cela ne fonctionne pas (aucune erreur n'est renvoyée, il n'envoie simplement pas de réponse) Est-ce que quelqu'un sait quel est le meilleur moyen de mettre en œuvre l'architecture précédente? avait?
Merci beaucoup!
Cela me me incluez pas laisser un commentaire dernier alors voici le plein: Mais je veux compléter la demande dans un autre acteur.Ma requête est passée du contrôleur à l'acteur 1 -> acteur2 -> acteur3 -> acteur4. Et en utilisant "demander" chaque fois que je le passe à l'acteur suivant, diminuera les performances car il devra renvoyer la réponse à chaque acteur (acteur4 -> acteur3 -> acteur2 -> acteur1 -> contrôleur). – sid802