多くのWebリクエスト(〜300000)を作成するスクリプトがあります。これは、問題は、各関数は非同期でファイルディスクリプタを使用してそれぞれの要求、何千ものを作っているので、私はToo many open files
例外に実行されるということです。この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"))
ようになります。
私はそれぞれが独自のクライアントとのバッチを作るなるように、私の機能を再編成しようとした:
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
})
})
}
しかし、これは早期に終了するため、理解させる(すべてのエラーメッセージまたは例外なし):
(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"))
私はあまりにも多くのファイル記述子を開くことなく、HTTPリクエストを大量に作るための正しい方法を探しています。