Как сделать большое количество запросов GET с StandaloneAhcWSClient - PullRequest
0 голосов
/ 13 апреля 2019

Как сделать очень большое количество простых запросов get с помощью StandaloneAhcWSClient в Scala? (это стандартный http-клиент в комплекте с платформой Play2). В моем случае я получил ~ 100K GET запросов на внешний API. Future.traverse() не обрезает его, есть ли лучший подход, может быть, способ обработать список URL-адресов вроде потока?

Вот код, который у меня сейчас есть: https://scastie.scala -lang.org / HgrIyR23TmG12j3MzMCxUw

Он работает до определенного количества URL-адресов в списке, но разбивается на большое число с исключением java.lang.IllegalStateException: failed to create a child event loop

1 Ответ

0 голосов
/ 17 апреля 2019

Вот что я закончил:

import play.api.libs.json.JsValue
import akka.actor.ActorSystem

import scala.concurrent.{Await, Future}
import scala.concurrent.duration.Duration
import scala.concurrent.ExecutionContext.Implicits.global
import play.api.libs.ws.StandaloneWSClient
import akka.stream.ActorMaterializer
import play.api.libs.ws.ahc.StandaloneAhcWSClient
import play.api.libs.ws.JsonBodyReadables._
import play.api.libs.json._

implicit val system: ActorSystem = ActorSystem()
system.registerOnTermination {
  System.exit(0)
}
implicit val materializer: ActorMaterializer = ActorMaterializer()

def getAllRecApiResponses(urls: List[String])(
  implicit actorSystem: ActorSystem,
  materializer: ActorMaterializer): List[JsValue] = {
  implicit val wsClient: StandaloneWSClient = StandaloneAhcWSClient()

  val res: Future[List[JsValue]] = Future.traverse(urls)(urlString => {
    wsClient.url(urlString).get().map(_.body[JsValue]).recover {
      case ex: Exception => {
        println( s"Url call returned exception for url $urlString: $ex" )
        JsNull
      }
    }
  }) andThen { case _ => wsClient.close() }

  Await.result(res, Duration.Inf)
}

val result = getAllRecApiResponses(List.fill(10)("https://jsonplaceholder.typicode.com/todos/1"))

result foreach println

Со следующим build.sbt:

scalaVersion := "2.11.12"

val liftVersion = "2.6"

libraryDependencies ++= Seq(
  "com.typesafe.play" %% "play-ahc-ws-standalone" % "2.0.3",
  "com.typesafe.play" %% "play-ws-standalone-json" % "2.0.3",
  "com.typesafe.play" %% "play-json" % "2.7.2"
)
...