Ich habe ein Skript, das eine Menge Web-Anfragen (~ 300000) macht. Es sieht so etwas wie diesesBatching-Anfragen mit play.api.libs.ws
// Setup a new wsClient
val config = new NingAsyncHttpClientConfigBuilder(DefaultWSClientConfig()).build
val builder = new AsyncHttpClientConfig.Builder(config)
val wsClient = new NingWSClient(builder.build)
// Each of these use the wsClient
def getAs: Future[Seq[A]] = { ... }
def getBs: Future[Seq[B]] = { ... }
def getCs: Future[Seq[C]] = { ... }
def getDs: Future[Seq[D]] = { ... }
(for {
as <- getAs
bs <- getBs
cs <- getCs
ds <- getDs
} yield (as, bs, cs, ds)).map(tuple => println("done"))
Das Problem ist, dass ich in eine Too many open files
Ausnahme ausgeführt werden, da jede Funktion asynchron Tausende von Anfragen zu machen, von denen jede eine Dateibeschreibung verwendet.
Ich versuchte reorganisieren meine Funktionen, so dass jeder einzelne Chargen mit ihren eigenen Client machen würde:
def getAs: Future[Seq[A]] = {
someCollection.group(1000).map(batch => {
val client = new NingWSClient(builder.build) // Make a new client for every batch
Future.sequence(batch.map(thing => {
wsClient.url(...).map(...)
})).map(things => {
wsClient.close // Close the client
things
})
})
}
Aber dies bewirkt, dass die für Verständnis vorzeitig zu beenden (ohne Fehlermeldungen oder Ausnahmen):
(for {
as <- getAs
bs <- getBs // This doesn't happen
cs <- getCs // Or any of the following ones
ds <- getDs
} yield (as, bs, cs, ds)).map(tuple => println("done"))
ich für den richtigen Weg suchen nur eine große Anzahl von hTTP-Anfragen zu machen, ohne zu viele Dateideskriptoren zu öffnen.