Я довольно новичок в мире Akka, и мне нужно перенести проект с Spray на akka-http.Заполнение запроса за пределами основного контроллера в Akka-http
В аэрозоле маршрут был типа Route = RequestContext ⇒ Unit
.
Но в akka-http, это тип Route = RequestContext ⇒ Future[RouteResult]
.
Так что в брызгах мы часто обрабатываем и выполняем наши запросы через цепочку Актеров (вне основного контроллера), используя только огонь и забываем, поэтому нам не нужно было «спрашивать», и производительность была великолепной , Теперь мы должны использовать «спросить» каждый раз, когда мы передаем запрос другому Актеру (исправьте меня, если я ошибаюсь)
Я много искал, и я нашел несколько вариантов, которые я не уверен если они полностью удовлетворяют меня (необходимость заполнить запрос у другого Актера без необходимости вернуть его обратно в контроллер). Так вот, где вы могли бы мне помочь :)
Вариант 1: Использование onSuccess
/onComplete
ли с помощью этого заблокировать мой главный контроллер получать больше запросов?
Вариант 2: Использование Future
с и использованием RouteResult.Complete
Я нашел следующий пример в 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
Но это на самом деле проходит ответ обратно каждый раз, когда к предыдущему Актер (отправитель), пока не достигнет основного контроллера. Другое дело, об этом варианте является то, что в коде, он говорит:
/**
* 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.
*/
Так что я не уверен, если это рекомендуемый способ сделать это.
Я попытался использовать requestContext.complete() в другом актере, но он не работает (ошибка не была выбрана, просто не отправляет ответ) Кто-нибудь знает, что лучший способ реализовать предыдущую архитектуру мы имел?
Большое спасибо!
это не позволит мне изменить меня последний комментарий, так вот полный один: Но я хочу выполнить запрос в другом Актере.Моя просьба передается от контроллера к actor1 -> actor2 -> actor3 -> actor4. И используя «спросить» каждый раз, когда я передаю его следующему актеру, будет снижаться производительность, так как он должен будет передать ответ каждому актеру (actor4 -> actor3 -> actor2 -> actor1 -> controller). – sid802