見出し画像

Kaigi on Rails 2024に参加してきました!

10/25(金)、26(土)に@有明セントラルタワーホール & カンファレンス(東京)で行われたKaigi on Rails 2024に参加してきました。

技術カンファレンスに参加する旨みは、普段の業務では触らない技術を知るきっかけになったり、他社事例を聞くことで自社システムへの理解が深まったりすることだと思います。

私は今回が初参加だったんですが、HotwireやGraphQL、Solid Queue、OmniAuthなどの技術についてや、他社事例(テスト時間の高速化とか、ERBからViewComponentへの移行とかPackwerkを用いたリファクタリングとか)からさまざまな知見を得ることができました。

本記事では個人的に面白かったセッションをいくつかピックアップして紹介していこうと思います。


タイムテーブルはこちらです。

ちなみに弊社のバックエンドはRailsをメインに利用しています。なので私は普段からRailsの恩恵を受けまくっていますし、私にとってRailsはとても好きなWebアプリケーション開発フレームワークです。

印象に残ったセッション Day1

基調講演

めっちゃ良かったのでシンプルに内容をまとめます。

  • Ruby on Railsの"Rails"とはRails newからIPOまでの道のりのこと。

  • サービス成長するにつれてRailsから外れてしまう。

  • Rails framework gives you structure.

    • Ruby on Railsは構造を提供してくれるが隙間があり、その隙間をそれぞれが埋めようとして歪ませる。

  • Rails Way gives you guidance.

    • Rails Wayは哲学でありそれを追求することで生産性が保たれる。

  • Rails Wayに従って隙間を埋めるためのガイドがLayered Design for Ruby on Rails Application

Railsの仕組みを理解してモデルを上手に育てる - モデルを見つける、モデルを分割する良いタイミング -

こちらのセッションは基調講演の内容に近い内容でした。

Fatモデルという問題提起から始まって、その対処法としてイベント系エンティティを切り出したり、POROにロジックを切り出したり、FORMオブジェクトを使ったりという方法が提案されていました。

よくある方法では、サービスクラスに実装してcallメソッドで呼び出すというプラクティスもありますが、Rails Wayに近い形でいうとサービス層自体を推奨しないということでした。

自分も以前texta.fmを聴いてこの手法は知っていて日常の業務で使おうと思って試したこともあるのですがまだまだイベント系エンティティの切り出しとかがしっくりこない感じがある。あとは単純に既存のデータモデルの設計に影響を受けるので完全に自由に設計できるわけでもないので難しいと感じていました。このあたりは日々鍛えていきたいなと思います。

また発表者の方のzennの記事で「Railsの練習帳」というのがあるらしく、こちら宿題としてやっていこうと思いました。ありがたすぎる。

Sidekiqで実現する長時間非同期処理の中断と再開

デプロイ時に長時間非同期処理が残ってしまっている場合に今までは指差し確認を行なっていたが、ジョブの中断・再開処理を実装して解決したという発表です。

ただ冪等性を確保した実装をするだけでは処理が最初からやり直しになってユーザ体験が下がってしまったり、想定外の箇所で停止した場合にメールが二重送信されてしまう等のリスクがあるという課題があります。

これらの課題を解決する中断処理と再開処理はどうあるべきかから考えて設計・実装していったところが勉強になりました。

[中断処理]
Sidekiqのプロセス停止を検知して任意のタイミングで非同期処理を停止させること
[再開処理]
再開した非同期処理を中断した箇所から処理を継続させること

この中断・再開処理をRSpecでテストする方法も勉強になりました。

and_wrap_originalという元のメソッドをそのまま呼び出しつつ追加の処理をかけるソッドを使うと、任意のタイミングで中断が発生することを再現できるそうです。

発表の最後にはSidekiq Iterationという機能が紹介されていました。

This means that the job can be decomposed into a sequence of elements to process; Sidekiq can stop and restart the job anywhere within this sequence using a cursor.

Iteration · sidekiq/sidekiq Wiki

中断時に進行状況(カーソル)を保存し、再開時には保存したポイントから処理を再開できるそうです。コールバックも充実しているのでこれで実現できそうですが、まだベータ版なのでproduction利用はもう少し先になりそうです。

リリース8年目のサービスの1800個のERBファイルをViewComponentに移行した方法とその結果

8年にわたるViewの運用で色々な課題が見えてきたのでViewComponentへの移行を決断し、移行作業には自動変換スクリプトを用いて行ったという発表でした。

ERBの問題点として挙げられていたのがこの3つです。

  • Viewファイルを読まないと必要なパラメータがわからない

  • 一貫性のないパラメータの渡し方

  • テンプレート内のロジックの多さ

ViewComponentを使うとコンストラクタでパラメータを渡せるので必要なパラメータが一目瞭然になるのと、パラメータの渡し方の一貫性も保証できます。

移行によるパフォーマンス改善も期待されていましたが、実測値ベースでは差は見られなかったとのこと。

ERB: 93.4ms
ViewComponent: 93.1ms

私も前職でJavaのフレームワークの移行で多くのviewのファイルの移行をしたことがあるので懐かしかったです。私の場合は自動変換スクリプトを作れず断念してパワープレーでやりましたが、エンジニアとしてあるべき姿を魅せられた感じがします。個人的に圧巻の内容でした。

ERBのパースの部分とか、変換ロジックの話がかなりすごかったのと、rspecも自動生成してたのが強すぎました。

パースした後に手に入る抽象構文木をどうこうという話をしていたけど全く理解できませんでした。悔しい。

また、この自動変換スクリプトは普通にいい値段で売れるくらいの価値あると思いました。120時間くらいで作ったらしいけど本当にすごい。

ActionCableなら簡単? 生成 AIの応答をタイピングアニメーションで表示。実装、コスト削減、テスト、運用まで。

生成AIの応答をタイピングアニメーションで滑らかに表示する上でActionCableを入れると簡単に実装ができますが、実運用を考えると色々な課題が見つかってくると言う発表でした。

実運用ででてくる課題で言うとこの辺りでそれぞれどのように乗り越えたのかが非常に勉強になりました。

  • コネクションの占有問題 -> ActionCableを実行するサーバはスタンドアロンとして実行する

  • LLMの応答時間が長い場合 -> Sidekiq使って非同期処理

  • 非同期処理にRedisアダプタを使うと返ってくるトークンの順序が保証されなくなる問題 -> ActionCableにインデックス番号を伝えて組み直す

  • テストにおけるコスト削減 -> VCR使ってリクエスト数を削減

色々なことを気をつけながら実装しく流れがめちゃくちゃわかりやすく超勉強になりました。

そのほかで印象的だったのは発表者が「Railsで新しいことをやろうとしたときはRailsガイドを読んだ方がいい。」と言っていたことです。自分はそんなにRailsガイドに頼ってこなかったのでこれからはゴリゴリ使っていこうと思いました。

印象に残ったセッション Day2

都市伝説バスターズ「WebアプリのボトルネックはDBだから言語の性能は関係ない」

RubyとGOのHTTPサーバで性能を検証した話がとても勉強になりました。

RubyはGVLという仕組み上、1リクエストあたりのCPUを使う計算処理時間がI/O時間に比べて大きくなってくるとGOで実装したHTTPサーバ(GOMAXPROCS = 10)と比べてrpsやrequest timeに差が出てきてしまう。

実験では、「I/O時間」と「CPU処理時間」の割合を調整しながらベンチマークを取っていて、「CPU処理時間」の割合が大きいエンドポイントの場合は最大10倍くらいの性能差が出ていました。(実験の細かい条件については後日スライドか動画が公開されたら参照してみてください。)

後半はRailsサーバのチューニングの話になりましたが、CPU処理時間の割合を元にスレッド数を調整する方法や、プロファイラを使ってCPU処理時間の割合が大きい処理を改善していく方法が紹介されていました。

例示されていたもので言うとこの辺りになります。

  • JSON.parseは結構CPU使っているのでOjに置き換えるとめっちゃ早くなる

  • mysql2も結構CPU使っているのでtrilogyに置き換えたら10%くらい早くなる

言語特性とかpumaのリクエスト処理機構の仕組みまで掘り下げた話が本当に勉強になりました。

ActiveRecord SQLインジェクションクイズ (Rails 7.1.3.4)

SQLインジェクション対策としては以下の3点を意識する。

  • SQLフラグエントを受け取るメソッドを一定把握する

    • User.order("age: #{params[:order]}")は任意のSQLを実行できてしまう

  • クエリメソッドへ外部入力を雑に渡さない

    • User.where("name = #{params[:name]}")は任意のSQLを実行できてしまう

  • クエリメソッドへ外部入力を渡す時は以下のいずれかを行う

    • エスケープが確実に適用される形式を選択する

    • 位置指定ハンドラ or 名前付きハンドラを利用する

    • sanitize_sql_arrayなどのsanitizeメソッドを組み合わせて利用する

    • 渡される値が制限されるような入力値チェックを行う

Rails7.2からBrakemanというセキュリティ脆弱性を静的解析するためのgemがあるっぽいけど偽陽性は多いのでignoreリストみたいなもの作って運用でカバーする必要があるっぽいですね。

Sidekiq vs Solid Queue

2024年時点ではActiveJobのアダプターとしてSidekiqが有力ですが、Rails8.0からデフォルトでSolid Queueが採用されます。「SidekiqからSolid Queueに移行する必要があるのか?」や、「これからRails newする場合はどっちを採用すべきなのか?」という疑問を持っている方は必見の発表です。

ストレージ面、インタフェース面、機能面の3点から比較した結論としては下記の通り。

SidekiqからSolid Queueへの移行はするべき?

  • SidekiqからSolid Queueに移行することは基本的にメリットが薄い

  • Sidekiq EnterpriseやProが高いよという場合のコストカットくらい

  • あとはRedisを減らして運用負荷を減らすとか

新しく作るとしたら?

  • ジョブをあまり使わないとしたらSolid Queue

  • ジョブをたくさん使うならSidekiq

  • 中間のサービスならSidekiq特有の機能で欲しいものがあればSidekiq

実績でいうとSidekiqは2万ジョブ/秒だが、Solid Queueは2000万ジョブ/日らしい。本当に要件次第になるとは思いますが調べるべきポイントが明確になったのはよかったです。

Identifying User Identity

サービス開発でUserモデルについてより深く再考してみるという内容です。「ユーザーのアイデンティティとは何か?」というところから考えて、「どのようなテーブル設計にするのか?」、「ユーザの登録、ログイン、退会をどう表現するか」、「ユーザのステータスをどう管理するか」、「管理者ユーザとユーザの権限の違いをどう乗り越えるのか」といった現実的な問題を、既存のパラダイムに縛られない本質的な視点から気持ちよく解いていきました。

発表を聞き終わったあとは脳みそが揺れるくらい良い内容でした。

こーゆー話聞くと本当にKaigi on Rails来てよかったと思いますし、自分でもアプリケーションを0から作りたくなりますね。

基調講演

スタッフエンジニアの島田さんの貴重な貴重な基調講演。ソフトウェアを設計する際に大事だと思っていることを話していただきました。

  • 全体が機能するように設計すること

  • 設計時点ではわからないことが多いので変化に向けて設計する

  • 変化に向けた設計とはオプションを増やすこと

  • 「オプションを増やす設計」とは「何にでも対応できるような構造や仕組み」ではなく「どの方向にも進めるようにシンプルに保つこと」

  • その上で本当の難しさは「シンプルさを保つこと」

  • シンプルさを保つには修復し続けることが必要

  • 修復とは「元の状態に戻す」のではなく、「変わった後の全体と再度調和させる」こと

  • お手本となるソフトウェアはRailsである

修復という概念をクリストファー・アレグザンダーを引用して説明していたのがオシャレでした。エンジニアなら誰でもよく用いる「設計」という言葉の捉え方が高度すぎて素敵でした。

一般的に何かを修復するということは、本質的に、私たちはそれを元の状態に戻そうと考える。このような修復は一時的な継ぎはぎ細工であり、静的で、閉鎖的なものである。
だが、修復という新しい言葉の概念では、あらゆる実態は常に変化するとみなし、あらゆる時点での現状の欠点を、新たな状態を定義する出発点とみなすのである。
このような意味で、修復の概念は創造的で、動的で、開放的である。

クリストファー・アレグザンダー 時を超えた建設の道

まとめ

Kaigi on Rails 2024は想像以上の収穫がありました。

印象に残ったのは発表者の何名かが「Railsガイドは良いよ」といっていたことです。私はRailsエンジニアながらあまり目を通したことがなかったのでこれからちゃんと読み込んでいこうと思いました。(大反省)

また、技術を深く知るとビジネス課題(機能要件や非機能要件を満たすだけではなく移行工数やコスト構造の改善など)をクリティカルに解決できるということがひしひしと感じました。このレベル感が自分がエンジニアとして目指したいところだと思いました。

そして、基調講演でも言われていたRails Wayについてもちゃんと自分の思想に取り入れていかないといけないと思いました。

本当は全ての発表を紹介したいくらいどれも示唆深い内容でした。とても良い時間だったので来年も参加したいなと思いました。

来年は東京駅 JP TOWER Hall & Conferenceです!


いいなと思ったら応援しよう!

あたまがきんに君
よろしければサポートお願いいたします。いただいたサポートはクリエイターとしての活動費に使わせていただきます!

この記事が参加している募集