追記
やっぱり、並列コレクションを使うのはやめて、Future 使って、Execution Context とかをちゃんと設定する方法にした。
が、一応、以下の内容はそのまま残しておく。
並列コレクションを使う動機
今、いろんな API からデータを取ってきて、それらを検索可能にするっていう(元々は自分用の)サービスをちょこちょこ作っている。(興味のある方は以下のリンクより使ってみて、是非フィードバックを下さいませ↓)
Track Down Anything on GitHub, Slack or Google Drive | Commet
いろんな API からデータを取ってくるので、直列で実行すると、どっか1箇所の API が不調だったりしてレスポンスが遅いと、それに引きずられてしまうので、並列化しようと思った。
コード
元々のコードは、大雑把にはこんな感じ。
SomeDatabase.findAllApiEndpointsToCall.foreach { apiCall =>
apiCall.execute
}
これを並列化しようとして、以下のコードにした。
# par をつけた
SomeDatabase.findAllApiEndpointsToCall.par.foreach { apiCall =>
apiCall.execute
}
ログをみると、
02:08:35.008 [ForkJoinPool-3-worker-5] INFO xxxxx
という感じで、別スレッドで動くようになったようだけど、スレッド名が常に同じ=1つのスレッドしか使われていないらしい。
以下のドキュメントを見ると、設定変更出来るらしいので、やってみた。
Parallel Collections – Configuring Parallel Collections – Scala Documentation
val apiCalls = SomeDatabase.findAllApiEndpointsToCall.par
# TaskSupport なるものを作成して、コレクションのプロパティにセット
val taskSupport = new ForkJoinTaskSupport(new scala.concurrent.forkjoin.ForkJoinPool(4)) # 4並列
apiCalls.tasksupport = taskSupport
apiCalls.foreach { apiCall =>
apiCall.execute
}
これで、とりあえず並列で処理されるようになった。
Continue reading Scala の並列コレクションが直列でしか動かないと思ったら・・・