Я смиренно возвращаюсь к сообществу, поскольку сейчас я явно слишком глубоко увяз.
Итак, я пытаюсь вернуть два фьючерса (в Play 2.5.2 в Scala) на экран в виде модулей, которые появляются на экране после их завершения. Я пробовал довольно много способов сделать это. Во-первых, отметим, что мне удалось успешно транслировать два источника с повторяющимся расписанием:
def streamAction = Action { request =>
val source1: Source[String, NotUsed] = unfoldAsync(NotUsed) { _ ⇒
sc.makeServiceCall("stream1").map(x ⇒ Some(NotUsed → x))
}
val source2: Source[String, NotUsed] = unfoldAsync(NotUsed) { _ ⇒
sc.makeServiceCall("stream2").map(x ⇒ Some(NotUsed → x))
}
Ok.chunked(source1.merge(source2))
}
Где sc.makeServiceCall
относится к:
class ServiceClient @Inject() (ws: WSClient) {
def makeServiceCall(serviceName: String): Future[String] = {
ws.url(s"http://localhost:9000/mock/$serviceName").get().map(_.body)
}
}
Который звонит:
class Mock @Inject() (actorSystem: ActorSystem)(implicit exec: ExecutionContext) extends Controller {
def mock(serviceName: String) = Action.async { request =>
serviceName match {
case "async1" => respond("asy1", 0.second)
case "async2" => respond("asy2", 3.second)
case "async3" => respond("asy3", 5.second)
case "stream1" => schedule("first", 500.millisecond)
case "stream2" => schedule("second", 2000.millisecond)
}
}
private def schedule(data: String, delay: FiniteDuration): Future[Result] = {
akka.pattern.after(delay, actorSystem.scheduler){Future.successful(Ok(data))}
}
private def respond(data: String, delay: FiniteDuration): Future[Result] = {
val promise: Promise[Result] = Promise[Result]()
actorSystem.scheduler.scheduleOnce(delay) { promise.success(Ok(data)) }
promise.future
}
}
Итак, это работает (как уже упоминалось) с выводом потока следующим образом:
первыйпервыйпервыйвторойпервыйпервыйпервыйпервыйвторойпервыйпервыйпервыйпервыйвторой
Но при попытке вывести два фьючерса, когда они завершатся (только по одному разу), я не могу. Я пробовал это:
def outputAction = Action { request =>
val source1: Source[String, NotUsed] = Source.fromFuture(sc.makeServiceCall("async1"))
val source2: Source[String, NotUsed] = Source.fromFuture(sc.makeServiceCall("async2"))
Ok.chunked(source1.merge(source2))
}
Это просто выводит все сразу (когда завершится 2-е будущее)
asys1asys2
Что я делаю неправильно?
-N
. - person Cyrille Corpet   schedule 06.06.2017Play
и cURL, решенные с помощью -N. Однако они не были связаны с объединенными потоками (это было в Play-2.3.8, где потоки предъявляли искIteratee
, а не akka-потоки). - person Cyrille Corpet   schedule 06.06.2017