皆様こんにちは、メドピアのサーバーサイドエンジニアの内藤(@naitoh)です。
RubyKaigi 2026 に参加されていた皆さん、お疲れ様でした。 開催直前の地震や羽田空港の管制システムトラブルで最初はどうなることかと思いましたが皆様無事に辿り着けましたでしょうか。 自分は飛行機が欠航しましたので、急遽、新幹線に振替を行い北海道新幹線のありがたさを噛み締めました。

いろいろありましたが、RubyKaigi のセッションの中で特に印象に残ったセッションをご紹介させて頂きます。
タイムテーブルは下記から確認ください。
Portable and Fast - How to implement a parallel test runner
最初に Red Data Tools での開発の取り組みで「テストを高速化できないか」という気づきが発端になったという Portable and Fast - How to implement a parallel test runner を紹介させて頂きます。
Rails な皆さんはテスティングフレームワークとしてたいてい RSpec (もしくは Rails 標準の minitest)を使っていて、test-unit はご存知ないのではと思いますが、今回は gem として開発が続いている test-unit の並列化を並列実行させて早期にテスト完了させる取り組みになります。
参考: Rubyのテスティングフレームワークの歴史(2014年版)
ちなみに、並列テストランナーとして、RubyKaigi 2023 の The Resurrection of the Fast Parallel Test Runner が今回の話の参考になります。
その中で、ActiveSupoort::TestCase で Minitest を使用している場合はスレッドベースで並行テストが可能。 Rails 6 以降で ActiveSupoort::TestCase で Minitest を使用している場合はデフォルトでプロセスベース(fork)で並列テストが有効になります。 プロセス間の同期には drb を使用しています。 ただ皆さんがよく使われている RSpec では並列テストはサポートされていないのが課題ということでした。
そこで並列テストランナーの test-queue は、RSpec や Minitest、test-unit などの各種テスティングフレームワークに対して、キューを分割させる形でプロセスベースでUNIX domain Socket or TCP/IP Socket を用いてプロセス間の同期を行い並列で動作させる事で、テストを早期に完了させることができるという話でした。
test-queue を使えば、test-unit も並列動作可能なのですが、各種テスティングフレームワークの内部APIを使用しているので内部APIが変更になると動作しなくなるリスクがあるので、最終的には各種テスティングフレームワーク自身で並列テストできる事が望ましいと最後に述べられています。
というわけで、前置きが長くなりましたが、今回は test-unit 単体で並列テストを可能にする取り組みです。
Portable (互換性) と Fast (テスト全体を効率良く早く完了させる)事を念頭に開発されたそうです。
- Portable : test-unit 自身がサポートしている Windows もサポートする必要がある。(fork ではなくWindows でもサポートされている spawn を使用する)
- spawn は親プロセスの状態を引き継がないので、親プロセスとの通信の仕組みを作る。
- プロセス間通信の仕組みで drb があるが、Ruby 3.3 以降で Bundled gem になっているため、外部ライブラリへの依存しない方針のため不採用。
- pipe を使ってプロセス間通信を行う。
- Unix: IO.pipe を用いた片方向通信のペアでの MainプロセスとWorkerプロセス間の個別の双方向通信。 (Marshal#dump/load でオブジェクトをやり取り)
- Windows: TCP/IP Socket を使った通信。
- Fast : 各Workerの処理状況を知っているのは各Worker自身なので、キューに並べられたテスト対象を、各Workerが自分でPullしテストを実行するため、遊んでいるWorkerが発生しない形にしている。
スレッドベースではなくプロセスベースにすることで、各Workerが効率良くテストを実行できる点や、テストを各Worker自身がPull する仕組みが効率的良さそうな点と、外部依存を極力排除しているので導入しやすさの点でよく考えられている印象でした。
ただ、Windows で TCP/IP Socket を使うのであれば、test-queue の様に UNIX domain Socket & TCP/IP Socket の組み合わせ方が処理的に似ているのでメンテナンスし易そうに思いました。というわけで、いろいろなプロセス間通信の特徴が理解できました。
Exploring RuboCop with MCP
次は MCPサーバー & クライアントの Ruby-SDK のお話です。
MCP は JSON-RPC を用いるのは知っていましたが、トランスポートの仕組みに stdio と Streamable HTTP (HTTP + SSE の拡張)という仕組みを用いるんですね。 ここで Rack 3 の streaming body を使って SSEに対応しているのが面白いですね。
Rubocop x MCP の取り組みの紹介で、cli での rubocop -A で自動修正 や、 cli の結果をAIエージェントが解釈すればいいのでは? 🤔 と思ったのですが、
Support built-in MCP server by koic · Pull Request #14911 · rubocop/rubocop · GitHub を確認するとエージェントはCLI出力を解析するのではなく、構造化された方法で(定義されたスキーマを使用して) RuboCopに問い合わせる事ができるので、より確実に処理する事が狙いだそうです。AI専用の応答を MCP経由で返すインターフェースですね。
弊社内でも管理画面にDB参照用のMCPサーバーを組み込むことで、AIエージェントからDBに対してSQLを発行*1し障害調査に使えるようになっており、今回の開発は大変ありがたいです。
Surviving Black Friday: 329 billion requests with Falcon!
続いてFalconを2025年のBFCM*2に本番投入したお話です。
Falcon はFiberベースで、I/Oバウンドなリクエストを効率良く処理するwebサーバーです。CPUバウンドなリクエストには効果はありません。*3
本番導入するにあたって、コードがFiber Safeである必要があります。
- スレッドをブロックするC拡張(rdkafka, gRPC, etc)は、そのWorker上の全てのFiberをブロックする。
ただ、どのようなケースで問題が発生するか事前には不明だったため、スケールテストや、カナリアリリースで問題が発生時は即座にUnicorn に切り戻す形で検証を実施することで、上記の問題を検出 & 修正しアップストリームにフィードバックされたとのことなので、途中から Falcon に切り替える場合は同様の検証が必要になりそうです。
なお、最初はUnicornモード(Worker毎に1リクエスト)で実施したとこのこと。これは Unicorn から Puma への移行でも同じ感じですね。
最終的なスループットの改善はUnicorn と比較して1割程度と控えめですが、Shopify ならその削減は相当なものになるでしょうし、Shopify レベルの環境で Falcon の本番導入実績ができたのはすごいですね。
おわりに
3日間にわたる RubyKaigi 2026 が終了しました。 最後は AOT コンパイラの Spinel に話題を持って行かれた気がしましたが、Ruby にはまだまだ進化の余地がありそうなので楽しみですね!
次回のRubyKaigiは 2027年4月14日から4月16日、場所は宮崎県宮崎市です。
是非読者になってください!
メドピアでは一緒に働く仲間を募集しています。
ご応募をお待ちしております!
■募集ポジションはこちら hrmos.co
■エンジニア紹介ページはこちら engineer.medpeer.co.jp
■メドピア公式YouTube www.youtube.com
■メドピア公式note
style.medpeer.co.jp