Rubyで特にRailsを使う際に「特定のドメインの変化によって別の処理の実行をトリガする」みたいなケースでは大抵の場合コールバックが使われる。 しかし、ぶっちゃけた話コールバックはかなり結合度の高いコードになってしまいがちで、実装的にスケールさせるためにはドメイン・イベントを使うほうが健全であると言える。 martinfowler.com
以下の記事はActiveRecordのコールバックがどのようなときによろしくない感じになるかを説明しており、非常に参考になる。一言で言うと、コールバックを使うことモデル自体に副作用が埋め込まれてしまう。一方でドメイン・イベントを使うことで、副作用がなにをするものなのか(メールを送る、外部のmBaaSを更新する、モニタリングサーバへメトリクスを送信する、等)を意識しないでよくなり、疎結合になる。 techracho.bpsinc.jp
さて、ドメイン・イベントの仕組みを実装する際、もちろんオンメモリなオブザーバ・パターンの仕組みを実装してもよいが、それは開発環境でしか使えない。プロダクションだと大抵APサーバは複数台構成のはずなので、Redisあたりにキューして複数の異なるAPサーバ上のサブスクライバがイベントを拾えるようにしたい。こうしておけばQueue-based Load Levellingもできるようになるので負荷分散もできてスケールする。
もっというならGCPのときはCloud Pub/Subで、AWSのときはSQSを使ったりできるようなプラガブルな感じになっていると最高だ。そんなものを求めていくつか探してみた。
dry-rb/dry-events
- みんな大好きdry-rbシリーズのPub/Subインターフェイス
- おそらく今回紹介するgemの中で一番シンプル。
Dry::Events::Publisher
というモジュールをミクスインしたクラスを作ってサブスクライバを定義すると、そのクラスに対してイベントをパブリッシュできる。これだけ。- 開発が比較的活発なのもいい
kris.leech/wisper_next
- 元々はwisperというPub/Subインターフェイスgemを作っていた作者による新しいライブラリ
WisperNext.publisher
とWisper.subscriber
というふたつのモジュールが用意されておりそれらをミクスインしたクラスを作るスタイル- パブリッシャクラスに対してsubscribeメソッドでサブスクライバクラスを追加していく。
- 特定のプレフィクスを持つイベントのみをサブスクライブできる機能もある。
- サブスクライブをする際に同期/非同期を選択できる。
kris.leech/ma
- 上と同じ作者のPub/Subインターフェイスgem。内部的には
wisper_next
が使われている。 - ライブラリの説明に "events as first class citizens." と書かれている通り、wisper_nextとの違いはパブリッシュ/サブスクライブするイベントをクラスとして定義できること。
Ma::Event
クラスを継承したクラスをイベントとして扱うことができる。 - それ以外には
Ma.publisher
とMa.subscriber
というモジュールが用意されており、それぞれをミクスインしたクラスを作るスタイルで特に目新しいものはない。
edisonywh/rocketman
- 今回紹介するgemの中で一番重厚かつ拡張性が高い。
Rocketman::Prodcuer
とRocketman::Consumer
のふたつのモジュールがいて、それぞれをミクスインしたクラスでemit
とかon_event
みたいなメソッドが使える。まあわかりやすい。- Redis上のイベントもサブスクライブできるアダプタが用意されている。現状はRedisだけだが、Registryという仕組みが用意されているので自前でカスタムの外部サービス用アダプタを作ることも可能。
- 初期設定では発行されるイベントがキューとしてメモリ上に保存され、Rocketmanのスレッドワーカーが処理していく仕組みになっている。これだとアプリケーションが死んだときキューをロストするので、もしキューを永続化したければRedisをストレージとして使うことができる。
- 作者によるとRedis PubSubやKafkaはそのあたりのミドルウェアをメンテしたりするコストがかかるが、Rocketmanを使えば実質アプリケーションレイヤで同じことができるので、すごく楽だよ、というのが売りらしい。
総括
アプリケーション層でPub/Subしたいだけならどれでもよさそう。もっとリッチに、イベントを永続化したり複数台構成で負荷分散とかに使いたい場合はrocketmanがよさそう。GCPとかAWSあたりのPub/Sub製品のアダプタも自前で作れそうだし。ただメンテされているのかどうかが若干気になるが...
- 作者:Roland Kuhn Dr.,Brian Hanafee,Jamie Allen
- 出版社/メーカー: Manning Publications
- 発売日: 2017/03/05
- メディア: ペーパーバック