mailcatcher とは
開発環境でメール送信するとlocalhostでメールを受け取り、受け取ったメールを読むためのWEBインターフェースを提供してくれるgemです。
つまり、今までだと「開発環境でメールを送信するとログに出力されていたテキストを拾っていた」のを、「WEBメーラーで見れる」ようになるのです。
thinとは
rackサーバと呼ばれる種類のgemで、同じ箱だとwebrick, unicon, puma, passenger, falconなどがあります。
それぞれのrackサーバには特徴があるのですが、rails5ではpumaが同梱されるようになったり、本番環境での使用実績も着実に積んできているしで、デファクトスタンダードはpumaになりつつあると思っている。
正直、thinは最近下火のように思う。では、mailcatcherはなぜpumaを使わずにthinを使っているのか。
thinを使っている理由
thinを使っている理由はsinatraでwebsocketを動かすためなのです。
(mailcatcherは、sinatraを使ったWEBインターフェースにwebsocketを使ってメールを受信するとリアルタイムに画面が更新されるようになっている。)
sinatraとpumaの組み合わせではwebsocketが動きません。thinだとwebsocketが動く理由は、EventMathineを使ったイベントループ型だからです。
https://github.com/sinatra/sinatra/issues/1035
所感
ここからは私の想像と感想なんですが、pumaのようなワーカースレッドモデルの場合、workerごとにリソースを確保するためwebsocketのコネクションを保持しておく場所を確保することができず、websocketのコネクションを張ってもリクエストを終えると破棄してまっている。一方、thinの場合は、イベントループ型なので切断されるまでコネクションを維持が可能、ということなんだと思いました。sinatraとunicornでも同じことが起きるのではないでしょうか。
あれ、railsのActionCableってpuma使ってない?pumaとwebsocketって動かないでしょ?と思ったので調べました。
ActionCableには、Redisのpubsubを使ってフロントとバックエンドを繋ぎ、websocketの接続をrails層で保持し続けるEventMathine相当の仕組みが実装されていました。
イベントループ型とワーカースレッド型はどっちを使うべき?
railsがワーカースレッド型の使用を前提とした機能を盛り込んできているあたりを見ると、これからもワーカースレッド型のサーバが使われていくように思います。
また、この意思決定の背景には、GVLが関係していると思っていて、イベントループ型のサーバはシングルプロセスなのでサーバのリソースを使い切りにくい、という事情も感じます。
おわり