poolcatというライブラリを公開した

以前gen_queueというライブラリを公開したが、またライブラリ公開のお知らせだ。今回作ったのはpoolcatという、いかにもpoolboyからパクったような名前であるが、poolboyはネーミングの参考になった。

これも大したものではないのだが、ワーカープール+タスクキューのようなものをやるライブラリを見つけられず、どうも同じものを何度も再実装していたのでgen_queueを使ってライブラリ化してみたら思いの他便利で、同じレポジトリの3箇所で既存のコードを大幅に削ることができた。デバッグの手間も省けるというものだ。改めてOTPの勉強になったという…ちょっと調べた限りだとRabbitMQの中にも似たような機能があるし、Riak CSの中にもある。たしかRiakの中にも似たようなものを作ってるはずで…と、まあ再発明よくないですよね。という結論に。

poolboyじゃダメなん?

poolboyはコネクションプーリングなど、「使われる」リソースの側をリミットをつけつつプールしておくためのものなので、今回のように「使う」側にリミットをつけるのが目的なので、poolboyだとそれなりにワークアラウンドが必要になる(というか、どうやってやるんだ?)ので、まあどうせ小さなコードだろうし素振りも兼ねて作ってみたのである。

なぜタスクキューが必要なのか?

Erlangは軽量プロセスが売りなのであって、タスクを非同期に処理したければ軽量プロセスをspawnしておけばあとはrunqueueがよしなにスケジューリングしてくれる…と思っていた時期が私にもあった。実際にやってみると、Erlang VMのスケジューリングは(当たり前だが)まあまあフェアなので、例えば10万個のタスクを同時にspawnすると、起動した軽量プロセスの中身によっては例えば10万個のファイルディスクリプタやTCPコネクション、それなりのメモリを確保しようとプロセスが動くわけで(ちなみに一番困るのはエフェメラルポートを使われるケース)、トータルでの性能は劇的に下がってしまう。これを防ぐためにはいくつか方法があると思うのだけど、ちょろちょろっと試行錯誤した結果やはり伝統的なこのモデルが便利だなあということに今更ながら気づいたのであった。それじゃErlang使ってる意味ねーじゃん!というツッコミに関していうと、軽量プロセスはすごいものでたとえばConsumerになる軽量プロセスそのものは100万くらいになってもおそらくErlang VMそのものはビクともしないのでやっぱりいつか便利になる時がくるだろうと信じている。

アイディア自体はここ1週間くらいなのだけど、実装は子供の相手をしたりしなかったりしながら、土曜日の1日でできてしまった。こういうしょうもないライブラリを作るのとかは得意だし、それでも1日でできるようになったというのは腕が上がったなあとか、転職した甲斐があったものだと思う。これを使ってちょっとしたサービスを作ろうと思っているのだけど、さすがにまだ無理かなあ。