その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

Kaigi on Rails 2025でasync gemを使ってSSE機能をRails Appで作るという話をしました #kaigionrails

speakerdeck.com

発表資料はこちらです。以下に資料に入れそびれた・話しそびれたことを以下に記しておきます。

実際のところSSEを導入したのはなぜなのか

今回例示したような「長い時間がかかる処理の進捗報告・完了通知」のような機能はポーリングでも実現可能なものであり、我々のプロダクトでも当初はポーリングを前提として設計がされていたのですが、以下のような理由からSSEを採用するに至って今回の発表に繋がっています:

  • ポーリングよりも基本的にはユーザー体験が良くなるはず (ポーリングの場合は変化までに高々インターバル秒かかる可能性がある) *1
  • 技術的な挑戦 (おたのしみ)

後者が地味に大事だと考えていて、何か新しい機能やサービスを作ったりする時に「既存のやり方」のみで固定化するのではなく *2、技術的に新しい取り組みをすることによって技術面・組織面での「実力」を高めたいというモチベーションが背景にありました。あと技術的に新しいことをやると純粋に楽しいですからね (楽しいだけではもちろん駄目ですが……)。僕はこれを「おたのしみ」と呼んでいて、新しいものを作る時にはできる限り取り組みたいと考えています。

Active Recordのコネクションをfiber nativeにする方法

スライドに書き忘れていました。

config.active_support.isolation_level = :fiber としてあげると、スライドの49ページ目に書いたようなworkaroundが不要になります *3

我々も当初この設定を入れようとしていたのですが、既に動いているそこそこの規模のシステムのisolation_levelを変更することに一定のリスクを感じたので見送っていたのでした。とはいえ多くの場合では問題が起こらない気もしますし (もちろん要検証)、少なくとも新たにrails newする時には問題無いと思うので、この設定でトライするのが良いと考えています。

MyModel.with_connection が使える

@ioquatixさんから発表後に教えてもらったのですが、表題のように MyModel.with_connection としてconnectionをborrowできるようになっているとのことです。べんり。

詳細については@ioquatixさんが書いてくださっているgistを参照してください: Show how `with_connection` and `lease_connection` interact. · GitHub

余談ですが、上記gistにあるように config.active_record.permanent_connection_checkout = :disallowed を設定に書いておくのは良さそうに思いました。

Rack 3以降は ActionController::Live を使わなくてもストリーミングレスポンスを返却できる

こちらについても@ioquatixさんから発表後に教えてもらいました。表題の通り、以下のように記述するとSSEでのレスポンスが可能なようです:

github.com

上記の例はFalconのものとなっていますがPumaでも問題無く動くとのことでした。これは知らなかった、良いですね。




ご覧の通り、async gemや数々の便利なライブラリ・ツールを作るなどのご活躍をされており、Kaigi on Rails 2025のキーノートスピーカーの@ioquatixさんから色々と教えていただけました。ありがとうございます。

テックカンファレンスはこういう交流ができるというのが良いところですね。

*1:ポーリングのほうが仕組みとしてシンプルであるというのは正。そしてSSEであってもコネクション数などの観点でのパフォーマンス優位性はそこまでないので……

*2:もちろん「型」を持っておくのは重要なのですが

*3:https://railsguides.jp/configuring.html#config-active-support-isolation-level