おもしろwebサービス開発日記

Ruby や Rails を中心に、web技術について書いています

Kaigi on Rails 2024で Sidekiq vs Solid Queueというタイトルで発表した

表題の通り、発表してきました。

Sidekiq vs Solid Queue | Kaigi on Rails 2024

スライドはこちら。

発表に至るまでの道のり

  • イベントの懇親会などでエンジニアの人と話しているときに「最近気になっているgemあります?」のような質問に「Solid Queueですかねえ」と返すと「なんですかそれ?」と聞かれたりする
  • イベントの懇親会などでSidekiqを使っている会社さんの中の人にProやEnterpriseつかってます?と聞くと「なんですかそれ?」と聞かれたりする
  • 新しいRailsで標準になったが、既存のRailsアプリケーションには影響がないもの(例: importmaps)に対して「Railsアップグレードするならこれ対応しないといけないですか?」と聞かれたりする

SidekiqとSolid Queueをお題にして話せばこの手の疑問を一気に解決できるかな、と考えたところで「Sidekiq vs Solid Queue」というキャッチーなタイトルが浮かんできて、これはプロポーザル通るだろうなという確信を得るに至りました。

さらにこれまでのバックグラウンドワーカーの変遷で少しずつ機能やインタフェースが洗練されてきたのと2024年現在の状況を踏まえてできたのがSolid Queueなんですよ、という説明をしたくてbackgrounDRbからのgemの解説を盛り込んだのですが、実際に資料を作ると時間の関係で歴史については大幅に説明を省略せざるを得なかったのが残念ポイントです。Delayed::JobのdelayメソッドについてとかResqueのジョブ実行ごとにforkする話とかしたかったのですが、それだと60分超の発表時間が必要なのでした…。

1日目

かつてないレベルで準備時間がなかったので、基調講演だけ聴いて残りは資料作成をしていました。発表者控室が用意されていておかげで作業に集中できて助かりました。

基調講演は、palkanの著書である Layered Design for Ruby on Rails Applicationsと主張は一貫しているんだけど本の内容そのままではなく、サンプルが複数ステップのフォームになっていて本を読んでいても楽しめる内容になっていてよかったな、と思いました。

Kaigi on Rails 2024に参加した - It's okay to be weird でnagatomiさんも書いてるけど、事前に講演者の著書を読むというプラクティスは現場での講演の理解度と楽しさが上がるので大変オススメです。

Layered Design for Ruby on Rails Applicationsは僕がこれまで読んできたRailsを拡張する系の本の中で一番自然にRailsを伸ばすやり方が採用されていて、日々の業務に組み込みやすいプラクティスが書かれている書籍なので日本語翻訳の話が進んでるっぽい?けど翻訳を待たずに原著を読む価値あるんじゃないかな、と思います。

僕は家族の写真以外に写真を撮る習慣が全然ないのですが、せっかくストラップの色分けなど rubyfriendsするための工夫があるのになにもしないのもつまらないな、と前回のRubyKaigiのときに思ったので懇親会のときに一回だけrubyfriendsしておきました。次回も思い出せたらrubyfriendsしておきたいところです。

そのほか懇親会では島田さんになるほどTCPソケット最高です!と感想を直接お伝えすることができたのがよかったです。自分が執筆した書籍、誰がどれくらい読んでいてどのような感想を持っているのかなかなかわからないので読んだものについてはなるべく感想をお伝えするのが良いな、と思いました。

僕は東京在住なのですが有明までの移動はそこそこ時間がかかるので、懇親会の会場であるワシントンホテルを予約*1していました。懇親会が終わってからエレベータで上にいくとすぐに部屋に入れて最高の体験。

2日目

資料も出来上がっているし発表練習もホテルで何度かできたので、かなりリラックスして発表に臨めました。できあがった発表内容はどちらかというと初心者〜中級者くらいに向けた内容になっていて聴いてくれた人たちにどれくらい刺さる話になっているか不安だったのですが、Xの反応などを見る限りそれなりに評価されたようで良かったです。

発表資料の最後のスライドにありますが、顧問先に週1程度の空きができるのでバックグラウンドワーカの話をもっと突っ込んで聞きたい、とか最新のRailsなんもわからんからキャッチアップしたい*2とかいう会社さんいたらなんらかの方法でお問い合わせください。

そしてKaigi on Rails2025へ

すでにKaigi on Rails 2025に情報がありますが、次回の開催は9/26~27なんですよね。そして僕の誕生日(かつ結婚記念日)は9月27日だったりします。なので来年はどういう形で臨むといいかな、と今から思案を巡らせているところです。(皮算用にも程がありますが)27日に登壇して家族とちょっと美味しいご飯を食べる、ができるといいかなあ。

*1:Kaigi on Railsの会場場所が公開されてすぐ

*2:ほかにもいろいろやります。詳細は https://blog.willnet.in/entry/2018/04/09/101808 参照

ginza.rb 第83回を開催してRails7.2のマイナーフィーチャーを学んだ

Ginza.rb 第83回 - Rails7.2のマイナーフィーチャーを学ぶぞ - connpass

第83回のお題は第82回に引き続いてRails7.2。メジャーフィーチャー以外の気になった変更についてgistにまとめたものを見ながらみんなで「これはいいですねえ」とか「これはどうなんだろうなあ」とか話していました。

gistはこちら。 Rails7.2のマイナーフィーチャーで気になったところ

gistははてなブログと違ってh2ヘッダのアンカーURLが取得しやすいので、あとでこの機能について誰かに話したい、となったときに便利。

時間がちょっと余ったので、やぎぬまさんの用意したgistも見てワイワイしました。'debug/prelude'の件とかconnectionの扱いが変わる件とかそういえばありましたね。

gistはこちら。 Ginza.rb 第83回向けの何か.

個人的な印象に残ったポイント

  • 7.1ではいったstrict localsについて、パースするのが大変じゃんという発想がなかった
  • render @postsのようにして部分テンプレートを描画するときに自動でpost_counter, post_iterationというローカル変数が生える、というのは知らない人が多そう

次回

次回は10月11日(金)に、Campfireのソースコードをみんなで眺める会をやる予定です。ご都合の合う人はお気軽にご参加ください(\( ⁰⊖⁰)/)

大阪Ruby会議04でRailsの関連について話してきました

表題の通り、先日開催された大阪Ruby会議04で「どうしてこうなった?から理解するActive Recordの関連の裏側」というタイトルで登壇させていただきました。

スライドはこちら。

登壇するまで

僕は常々なにかしらRails関連のテックな話がしたいな〜と思っています。以前ブログに書いたActive Recordで関連先を保存するときに気をつけることは自分的にはかなりの力作だったのですが、あんまり読まれてなさそうだったのでこの機会に解説をモリモリ足して発表するともう少し幅広い人にリーチできるかな、と思いプロポーザルを出してみました。そこまでキャッチーな話ではないので通る自信はなかったですが、結果として無事採択されてよかった。今回の発表は大阪Ruby会議04がなければ日の目を見なかった可能性は高いです。オーガナイザの皆様、貴重な発表の場をありがとうございます。

登壇資料はブログをベースにすればいいからすぐできるやろ、と甘く見ていたら発表にあたって調査が必要な箇所が複数あり結局ギリギリまでスライドを調整していました。プロポーザルを通すのはいいけど、通ると期限内にスライドを作らなければいけないという制約*1が毎回辛い><

登壇

前回の大阪Ruby会議03ではうっかり10分の発表枠を選択してしまい時間が足りずに大変だったので今回は即30分の発表枠を選びました。おかげで当日じっくり話すことができてよかった。前回に限らず最近は「時間が足りないので急いで話す」ことが多くなにも意識しないと急いで話してしまうため「ここで水を飲む」スライドをあらかじめ複数配置して強制的に一息つくようにしていました。一定の効果があったので次回もやりたい。

登壇内容は上でも書いたようにRailsの関連についてでした。Railsの関連は「普段とくに内部実装を意識することなく頻繁に使っているけど、意識し始めると無限に疑問が出てくるし内部実装について言及しているドキュメントはほぼないしコードを読んで理解するのも難易度が高い」機能になっています。30分ですべてを説明することは難しいのですが、関連実装の中でも特に難しいと個人的に思っている関連先の自動保存と双方向の関連付けについて噛み砕いて説明することで、仮に昔の自分がこれを聞いたらめっちゃ満足するであろう話になりました。

しかし当日ちゃんとスケジュールを見てみるとスポンサーLTを除いてRailsの話をするのは僕だけ*2で参加者の需要に合った話だったかな…?と心配になりましたが、登壇後に役に立つ話だったと(はすみさん以外からも)何人か言及いただいたので安心しました。

今回は家庭の事情により次の日の朝すぐに東京に戻らないといけなくて大阪観光はほぼできず、という感じでしたが会場あたりの街並みがたぶん大阪に住んでいた頃に何度か通った場所で、懐かしい気持ちになりました。来年はもうちょっと余裕を持ってこれるといいな。

SaveChainInspector

関連先の自動保存がどのような順番で起きるのか調査するときに使えるsave_chain_inspectorというgemを紹介しましたが、現時点では出力を標準出力決め打ちにしていたりとだいぶ素朴な実装になっています。個人的には現状の仕様で困っていないのですが、需要があったらログファイルに出力もできるようにするなどしてもいいかな、と思っているので需要があったらその旨教えて下さい :pray:

次回予告

次の登壇はKaigi on Rails 2024で「Sidekiq vs SolidQueue」というタイトルで話す予定です。これから登壇準備を頑張ります。

*1:制約ではない

*2:強いて言えばkinoppydさんがRails周辺の話であるHotwireの話をしている

ginza.rb 第82回を開催した

Ginza.rb 第82回 - connpass 第82回のお題はもうじきリリースされるはずのRails7.2。やぎぬまさんがRails7.2メジャーフィーチャについてのスライドを作ってくれていたのでこれに沿ってワイワイしました。

メジャーフィーチャーという建付けだけど機能というよりは「rails newのときに新しいなにかが生成されるようになった」というものが多く、これはもしかしたらサラッと30分くらいで終わるかもしれないな〜と思ったので マイナーフィーチャー用の資料を用意していたのだけど、いい感じに時間いっぱいまで盛り上がって終了。マイナーフィーチャーに関しては来月持ち越し。

メジャーフィーチャー中のトランザクション中でエンキューしないという機能は個人的には最高便利!と思っていたのだけど、「トランザクション中でエンキューが失敗したらロールバックする」ができなくなるというデメリットについて話が出て「その発想はなかったなあ」となりました*1

来月はRails7.2のマイナーフィーチャーについてワイワイする予定なので都合合う方はご参加ください。

*1:sidekiq pro以上を使っていれば Reliability Client でエンキューの失敗をサポートできる気もしないでもないけど

ginza.rb 第81回を開催した

コロナ禍から休止状態だったginza.rbを4年ぶりに復活させました。

Ginza.rb 第81回 - connpass

コロナ禍以降リモートで働くひとが増えたので都内でオフラインミートアップをしても集まらないんじゃないかな?と思っていたのですが、蓋を開けてみたら定員オーバーするレベルで嬉しい誤算でした。開催してみた感想はオフラインミートアップからしか取れない栄養素あるな〜でした。復活させてよかった。

今回のミートアップの内容は久しぶりの開催なのでみんなの近況を聞きたいな、と思い自己紹介拡大版としました。みなさんかわらず元気にやっているようでよかった。

自己紹介タイムのあと、僕のプライベートが忙しくなったこともあり再開にあたってなるべく省エネでミートアップできる方法ないかなあ…というのを相談させてもらいました。ただginza.rbらしさをキープしつつ省エネするのはなかなか難しいですねという感触。ありがたいことにこれまでのginza.rbの内容を評価してくれる声もあったのでしばらく従来通り開催しつつ様子を見ようかな、と思っています。

次回はRails7.2をお題にして7月26日(金)に開催する予定です。お題がキャッチーなときは公開してすぐ枠が埋まりがちなので、参加するモチベが高い人はginza.rbのslackやconnpass*1などに登録しておいて通知を受け取れるようにしておくとよいかと思います。

*1:再開にあたってdoorkeeperから移行しています

savanna.io をRails 7.2にアップグレードした

お仕事SNSsavanna.ioの開発を空いた時間でやっています。先日Rails 7.2のbetaが出たので試しにCIを回してみたらそれほど問題なくアップグレードできそうなのでサッと対応してアップグレードしました。以下対応した内容を書いています。

bulletを外す

bulletの依存でbundle installができなかったので、一旦bulletを外しました。 PRは出ているので取り込まれたら戻すのを検討します。

Support active record 7.2.0 by hatsu38 · Pull Request #707 · flyerhzm/bullet

enumの形式変更に対応

Rails7.0からenumの引数の渡し方が新しくなりました。7.2からは古い渡し方はdeprecatedになり、8.0からは新しい方式だけになる模様です。

# 旧
enum status: { unlooked: 0, looked: 10, read: 20 }
# 新
enum :status, unlooked: 0, looked: 10, read: 20

Allow new syntax for enum to avoid leading _ from reserved options by kamipo · Pull Request #41328 · rails/rails

savanna.ioではconfig/environments/test.rbで次のようにしてdeprecation warningのときに例外を発生させるようにしているので、Rails7.2にアップグレードしたことでCIが失敗しました。

config.active_support.deprecation = :raise

Rails7.2にアップグレードする際に必須の修正ではないですが、早く対応するに越したことはないので一緒に修正しました。

prepared statementの実行でエラー

Rails7.2にアップグレードすると、次のように文字列でクエリを渡している箇所でActiveRecord::StatementInvalidエラーになりました(コードは簡略化しています)

def not_todays_target
  User.joins(:conditions).where(
    'conditions.transfer_on - interval :duration = :today',
    today: Time.zone.today,
    duration:
  )
end

コードを追いかけて調査したところ、Rails7.1まで上記のクエリはprepared statementの対象外だったのがRails7.2から対象になったことが原因のようでした。intervalリテラルの部分をプレースホルダとして利用することはできないらしいので、クエリの書き方が悪いと判断してdurationの部分を文字列展開させることで対応しました*1

def not_todays_target
  User.joins(:conditions).where(
    'conditions.transfer_on - interval #{duration} = :today',
    today: Time.zone.today,
    duration:
  )
end

prepared statementの対象が変更になったのはこのPRが原因のようです。

Relation#where build BoundSqlLiteral rather than eagerly interpolate · rails/rails@8e6a5de

このPRは、DBのconnectionを使う機会をなるべく減らす一環で作られたものです。

これまでは例えばwhereメソッドの実行時にActiveRecord::Base.sanitize_sqlを利用してプレースホルダの置換を行っていました。このとき、利用するDBによるクォートの付け方の差異をconnectionを利用することで解決しています。このPRではプレースホルダの置換、つまりconnectionの利用を遅延させて、prepared statementを利用する設定であればそれを利用するようにコードを修正しています。結果として、これまでprepared statementを利用していなかったクエリが、prepared statementの対象になっています。

所感

思っていたよりも簡単にアップグレードできました。次はconfig.load_defaults 7.2にチャレンジしようと思います。

*1:durationはユーザ入力文字列ではないのでセキュリティの問題はありません

RubyKaigi 2024に行ってきました

  • ちゃんと書こうとすると一生書けなさそうなのでざっくりとまとめています
  • めっちゃ楽しかったです
  • 5/11~19まで沖縄を満喫しました
  • 前入りで旅行をしてからRubyKaigiに臨むと体力が0に近い状態からのスタートになるので、懇親会は欲張らずに1次会だけの参加にしてサッとホテルへ戻り体力温存を優先するのが良いな、という知見を得ました
  • 発表はだいたい一番大きい会場にいました
    • 3階席が空いていて居心地が良かった
    • こばじゅんさんやydahさんのパーサ関連の発表だけそれぞれB、C会場で聞きました
      • 僕もいちおうドラゴンブック読書会の末席にいるので、仲間を応援する気持ちでした
  • 観た中ではモリスさんのNamespaceの発表が一番ワクワクしました
    • Namespaceによって僕ら(Railsアプリケーションをつくる人)の生活がまた一段階便利になるんじゃないかな〜
  • 久しぶりのひとと直接会って「RubyKaigiは同窓会みたいですねえ」みたいな話をしていました
    • RubyKaigiは同窓会感もあるんだけど、通信簿感もある
      • この一年なにをしてきたか、が反映される
    • 各発表内容で「なんもわからん」というのは(最初のぺんさんの発表を除いて)なかったのでインプットはそれなりにできている
    • が、アウトプットはそれほどない
      • 仕事の中ではちょこちょこやっているのだけど、それをもっと広く公開する手間を掛けられていない
    • 英語もリスニング、スピーキングがまだまだ
    • 昔ほどは自分の時間が取れないんだけど、来年の4月をもっと楽しむためにがんばっていこ(\( ⁰⊖⁰)/)という気持ちになりました
  • 松山も楽しみにしています!!