東京 Ruby 会議 12 実行委員長のおしょうゆです。
素敵なレポートを参加者のみなさまに執筆いただきました。ぜひお読みください。
(おしょうゆ)
2016 年の東京 Ruby 会議 11 から 9 年、東京 Ruby 会議が帰ってきました。おかえりなさい。始動させたのはオーガナイザーのおしょうゆさん、それからコアメンバーの皆さんです。今回は神奈川県は横浜市鶴見区、まあ大体東京に収まる範囲の「東京」で開催されました。
このレポートでは、当日のトークのレポートや感想、それからトーク外、いわゆる「廊下」の様子や、スポンサーブースの様子、当日まで秘められていたオーガナイザーたちの「おもてなし」を紹介します。わたしは廊下が好きなので廊下のお話をします。それではどうぞ、追体験の旅へいってらっしゃい。
(sakahukamaki)
オープニングキーノートを務めた John Hawthorn は、昨年の RubyKaigi 2024 の登壇に来日している、カナダ在住の Ruby と Rails のコミッターです。
今回は John Hawthorn が勤務している GitHub 社における、GitHub のサービス開発と運用をテーマに冠したタイトルです。私たち参加者も、日頃の業務で使っているサービスなだけに、興味を持って聞いていた方も多いのではないでしょうか? 私もそのひとりで、ここでは聞いて印象的だったことを感想を交えてレポートします。
このキーノートは GitHub 社の Rails 運用の歴史から始まりました。かつての GitHub のサービス実装では rails/rails リポジトリをフォークして独自拡張された Rails を使っていたこともあったようですが、現在は rails/rails リポジトリのエッジをそのまま使っており、John Hawthorn が参画した頃には非常に素直な Rails アプリケーションとして構成されていたようです。Rails アプリケーション開発において、可能な限り Rails が用意しているレールに乗るという姿勢と、一時的にレールが外れることがあっても本道に戻すという徳を積み重ねることの大切さが伝わるオープニングです。
ここから GitHub の中が垣間見えるお題が次々と取り上げられていきます。個人的に「誰が話すトークか?」はトークへの期待に対して重要な点で、このキーノートでは Ruby と Rails のコミッターである John Hawthorn が誕生した環境はどのようなものか? という点が、John Hawthorn のトークとして期待するポイントでした。
この期待については、最新の Ruby と Rails をお仕事で使っている点について、具体的にそのような環境をどのように運営しているかで示されました。GitHub Actions を使って週次で rails/rails リポジトリの main ブランチをプルリクエストとして開き、それを本番環境に適用しているとのことです。デプロイの頻度は「差分を把握できる範囲」で小さくといった形で、常に rails/rails リポジトリのエッジを使っているというものではありませんでした。「あれ? 週一なら運用できそうでは?」と思った方は、Rails パイオニア企業に加わるはじめの一歩として、お手本として自社プロダクトに持ち帰ってみることを検討できそうなとても具体的かつ実践的なトピックでした。余談ですが、GitHub 社の機能である GitHub Actions を使って実現しているというのも、自分たちが欲しいものを自分たちで作って使っている形になっていて良いですね。
さらに、こういった環境で GitHub 社から生まれた複数データベース機能の活用事例については、単一障害点になりがちなデータベースに対してリードレプリカを用意する話が、運用面に掛かる話として挙げられていました。データベース更新のターゲットとなるプライマリーのデータベースと、リードレプリカではどうしても情報の鮮度に差異が起きるについて、GitHub にログインしているユーザーはフレッシュなプライマリーに接続し、不特定多数の匿名ユーザーはリードレプリカに接続させるという、データの性質と提供先するユーザーの属性を踏まえて負荷分散を考えるというというのは、運用まで見据えた指針の参考になりそうです。
なおエッジを本番適用しているのは Rails のみで、Ruby は週一で CI ビルドのみ行っているようでした。たしかに変更の差分把握の難易度は Ruby と Rails で異なるため、これも現実的なアプローチとして聞いていました。
リファクタリングなど日常的な改善についても触れられており、プロジェクトオートメーションがされているのは想定の範囲だとしても、改善の閾値を達成したら「よくやりました! 次の目標となる新たな閾値を設定してさらに改善しましょう!」と、手を動かしたメンバーを労うようなちょっとしたひと工夫のメッセージ出力がされているサンプルコードを示されていました。こういったコードを通したプロジェクトファシリテーション文化の一端を垣間見れたのも、印象的なワンシーンのひとつでした。
このような話が、コードが出てこない抽象論ではなく、良い塩梅に抽象化されたサンプルコードを示しつつ話は進むため、聞いている側としては自分の現場ではどのように手を動かせば実現できそうか? どの話を実現可能なチャレンジとして持ち帰ることができるか? を考えることができる構成で話は進みました。
GitHub 社が GitHub を使いながら GitHub を Ruby on Rails で開発している期待のトークを、期待以上の濃度と具体性で示された素晴らしいキーノートでした。明日の Rails パイオニア企業を育てるのは、このキーノートを聞いた会場のオーディエンスのあなたかもしれません。ひとりひとりに、そう語りかけていると思わずにはいられませんでした。
以上が参加レポートとなりますが、このキーノートは東京 Ruby 会議 12 に参加していたたくさんの Rubyist が聞いていました。GitHub 社の道具箱ともいえるこのキーノートは、さまざまな観点での感想があると思いますので、ぜひお近くの Rubyist と感想を交換してみてください。それぞれの Kaigi Effect でコミュニティを発展させていけると最高ですね!
(koic)
最後のキーノートでは、Kohei Suzuki さんが、CLI ツールの開発と ISUCON (競技型 Web アプリチューニングコンテスト) における言語移植の経験をもとに、Ruby と Rust の特徴を比較しました。Ruby と Rust といえば、Ruby3.1 で Rust 実装の YJIT が導入されて以降、注目を集めている組み合わせです。多くの Rubyist が Rust に興味を持ちつつも、使いこなせていないのが実情だと思います。発表ではどのように比較されるのか、非常に興味深い内容でした!
CLI ツール開発の観点では、Ruby の柔軟性と拡張性の高さが強調されました。Ruby では require
や const_get
を用いることで動的にコードを読み込み、機能を自由に拡張できます。この特徴により、カスタマイズ可能な CLI ツールの開発が容易になります。一方で、CPU 負荷の高い処理では GVL(Global VM Lock) の影響を受けやすく、並列化には工夫が必要です。また、JSON のパースにおいては、型チェックや存在チェックを自前で実装する必要がありますが、protobuf を活用することで型安全なデータ変換が可能になる点が紹介されました。
対して Rust は、静的型付けの影響でプラグインの配布や管理が難しくなるという課題が挙げられました。しかし、I/O を許可しない場合はEnvoy proxy のように WebAssembly を利用した拡張 が有効であり、I/O を許可する場合はhashicorp/go-plugin のように gRPC サーバーを起動する実行可能ファイルとしてプラグインを配布する手法が適しているとされました。さらに、スレッドを起動することでマルチコア並列処理が可能になり、高速な処理を実現できます。JSON のパースにおいても、Serde を活用することで型安全なデータ変換が簡潔に行える点が Rust の利点として紹介されました。
言語選択のポイントとして、拡張可能な CLI を作成する際には Ruby が適しており、静的型付けによる制約を受ける Rust ではプラグインの配布や管理が複雑になるため、Ruby の方がシンプルに実装できます。一方、並列処理が求められる場合には Rust が適しており、マルチコアの活用が容易であることがメリットとして挙げられました。加えて、複雑な JSON の処理においては Serde を利用できる Rust の方が、より簡潔な記述が可能になるとのことでした。
ISUCON における言語移植の経験についても語られました。この競技では、Go、Ruby、Rust、Python など様々な言語で実装された Web アプリを高速化することが求められます。Kohei Suzuki さんは、ここ数回の ISUCON で Go で書かれた基準実装を Ruby や Rust に移植する作業を担当し、その経験をもとにしたエラーハンドリング、リソース管理、Web フレームワークの違いについて比較を行いました。
Ruby では例外を用いたエラーハンドリングが主流ですが、Rust では Result 型と?演算子を活用したエラーハンドリングが一般的です。リソース管理の観点では、Go の defer、Ruby のブロック、Rust の Drop トレイトが比較されました。Web フレームワークについては、sinatra+mysql2 の Ruby スタックと、Axum+SQLx の Rust スタックが取り上げられ、Ruby の記述量の少なさと可読性の高さが評価される一方で、Rust の Derive マクロを用いた型安全なデータ変換の強みが紹介されました。全体として、書き方に大きな差はないものの、型が保証される分 Rust のほうが使いやすい場面があるとのことでした。ただし、ISUCON の競技環境では Rust のコンパイルの遅さがネックとなることもあるようです。
今回の発表では、Ruby と Rust の特性を比較しながらも「コードを短くする工夫」が両言語の共通点として挙げられました。Ruby ではメタプログラミングや DSL を活用することでコードの記述を簡潔にできます。一方、Rust では Derive マクロを利用することで型安全性を維持しながら記述量を削減することが可能です。さらに、両言語とも if や match/case を式として扱えるため、スッキリとしたコードが書ける点も共通しています。 CLI ツール開発や ISUCON での言語移植での経験を踏まえて、用途によって使い分けていくのが良いとのことです。
懇親会では、Kohei Suzuki さんのチームの半数が Rust を活用しており、CLI 用途で複数のツールを Rust で開発しているという話を伺いました。なかなか仕事で Rust を書く機会がない Rubyist も、CLI ツールの開発を通じて Rust を試してみるのも良いかもしれませんね!
(alpaca-tc)
ランチ明けは、前田 修吾さんによる自作の Ruby 製テキストエディタshugo/textbringer での生活の発表がありました。
発表は、エレファント・カシマシのアルバム『生活』に収録されている「晩秋の一夜」の歌詞から始まり、火鉢を囲む生活への憧れと新婚当時の思い出が語られ、そこから情報社会におけるノスタルジーの象徴としての端末環境へと話が展開しました。Ruby 製エディタを開発した背景として、そういった古いものへの憧れや、開発のシンプルさがあるそうです。
デモでは、選択範囲の文字を大文字にする upcase_region 機能の実装をライブコーディングで行いました。エディタをスライドにして発表をしつつ、その端末上でエディタ自身のコードを書き換えて、その場でコマンドを追加して実行するという、まさにライブコーディングの実演でした。さらに、日本語入力機能として T-Code を用いた入力や、Groonga を活用したメール機能についても紹介されました。
発表の中で、制作のすすめとして「SNS などの評価を気にせず、自分のためにソフトウェアを作ること」の重要性が強調されました。スライドには、宇野常寛さんの「庭の話」からの引用がありました。
人間は「どうしてもほしいがまだ世界には存在しないもの」を求めて (自分でつくるしかなくなり)「制作」をはじめる。 自分がほしいものを誰もつくってくれないので自分でつくるしかない、という思いを実現した時の快楽は他のものでは代替できない。
この言葉は、聴者である自分の心に強く響くものでした。他の聴者にとっても、プログラミングをはじめたばかりの頃の純粋な喜びを思い出し、自分のために何かを作るという本質的な楽しさを再認識するきっかけとなったのではないでしょうか。
「どうしてもほしいがまだ世界には存在しないもの」を自分で作り、それを自分の生活の一部として使い続ける。その姿勢にこそ、開発の醍醐味があり、Ruby と共に暮らすことの魅力があります。前田 修吾さんの発表は、ものづくりの原点を思い出させてくれる、刺激に満ちたセッションでした。
(alpaca-tc)
コラボレーションツール、チャットやオンライン授業など、複数の Web フロントエンドがリアルタイムに協調動作する必要のあるユースケースで、それらをいかにして同期させるかというテーマでした。既存のリアルタイムデータベースを使用するのではなく、Active Record を活用すべく、Rails と React の組み合わせで実現する方法について話されました。
バックエンドからフロントエンドに情報を送る際に重要なのは「何をどう送るか」というイベントの設計です。特にモデル間に関連がある場合には扱いが複雑で、場当たり的なイベント定義をしていくとモデル数の増加とともに破綻してしまいます。
ユースケースの分析から、データフローを一方向に制約し、「木構造を丸ごとリアルタイムに同期したい」という問題に帰着させ、それをどう実現するかという議論に移っていきます。Rails のモデルとこの木構造は単純には対応しないものの、画面ごとにデータの親子関係を考えることができ、それを木構造として扱っています。具体的な通知の実装方式として「どの単位でサブスクライブするか」「更新の事実だけを通知するのか内容も通知するのか」という 2 つの軸で整理し、メリット・デメリットが議論されました。
これらを実現するための一式を含む gem としてArSync を開発されているとのことです。発表は「JavaScript / TypeScript / ruby.wasm と Rails の組み合わせにはあまり試されていない可能性がまだまだありそう」「僕らは Ruby のポテンシャルをもっと引き出せるはず」とのメッセージで締めくくられました。
私はリアルタイム Web アプリケーションが大好物で、複数のスタックで実装した経験もあって、とても興味深く聞きました。ただ、複数のモデルが複雑に関連するようなものはあまり経験がありませんでした。発表では親が変わるケースや複数あるケースにも言及されており、これは大変そう……という気持ちになりました。現代 Web 技術と Ruby / Rails の新たな可能性、気になります。
(darashi)
『パーフェクト Ruby』の著者でもある ryopeko さんのトークです。
話の全体としては、Ruby を使った業務プロジェクトの課題を、関数型言語によるアプローチで解決するといった、ユニークなものでした。
なかなか現場で見かけることも少ない、curry
によるカリー化や >>
(あるいは <<
) による関数合成といった、Ruby で用意された関数型言語のパラダイムによる API が登場人物になります。聞いている私自身は、関数型言語からのパラダイムによる Ruby の API というと lazy
くらいしか実践的に活用できていなかったので、ryopeko さんの発想力の高さが非常に参考になったトークです。
マイナー機能を使いたい! といったような、目的と手段が反転しているような話ではなく、CSV 出力のカラムそれぞれに適用したい処理が異なるため、それぞれを処理する手続きを用意して、部分適用や関数合成をもちいたモジュール性ある解決を目指すといったもので、聞いている側として説得力あるトークでした。と思いきや、これは ryopeko さんのマジックだったようで、functional なアプローチを決めるとカッコイイというのは、良くも悪くもという両面があり用法用量は適切に用いるべきと、アクセルとブレーキを巧みに使い分けて話されていました。
実際的なところとして ryopeko さんがトークで話されていた functional な API 活用によるアプローチが、現場のプルリクエストとして出た時は「え? ちょっと。これ何やっているの?」的な反応もあったという点も、「それはそうかも」と現場の活きた話だなと思ったポイントです。
現場での functional なアプローチ適用事例を通して、まだまだ実践で使いこなせていない Ruby の可能性を感じさせられました。
(koic)
tokujiros さんの発表では、Ruby アソシエーション開発助成金にも採択されたReight の内部実装と利用方法について紹介されました! Reight は Ruby で実装されたレトロゲームエンジンで、Reight をインストールして起動することでゲームを作るための統合開発環境が立ち上がります。統合開発環境では、ゲームに表示させるキャラクターやコインなどをドット絵で作ったり、それをマップ上に配置したりといったゲームを作るための作業と実際のプレイができます。ゲーム中のキャラクターの操作や当たり判定などは game.rb に Ruby のコードで実装します。発表中に使われたコードがreight-examples に上がっていて、インストール後すぐに試すことができるので是非!
発表の中では Reight の技術スタックが紹介されていて、コンピュータグラフィックのライブラリである OpenGL を抽象化してるレイヤーの実装や統合開発環境のツールキット、ゲームを描画するコードを各部分の Processing 互換 API レイヤーなどなど、Reight を構成している各技術について知ることができました。私が前日の前夜祭でクリエイティブコーディングのワークショップに参加していたこともあり、Processing 互換 API レイヤーの話を聞いてる時には「おー、同じようにこうやって描画するのか!」と東京 Ruby 会議の中での繋がりを感じられてよかったです。
普段はゲームはする専門ですが、発表を聞いてゲームを作る方の楽しみや、それが普段使い慣れてる Ruby のコードでできることの良さを知り、自分も Ruby で趣味の幅を広げたいな〜を感じた発表でした!
(三谷 昌平)
yumu さんによる「Ruby × AWS で作る動画変換システム」は、GMO ペパボさんのハンドメイド EC サービス「minne」で新しくリリースされた動画投稿機能の設計や実装・運用について焦点を当てられていた発表内容でした。
Ruby による自前実装と AWS のマネージドサービスを組み合わせた設計となっており、それらを実装する上で導入した 2 つの gem である ffmpeg の動画変換を Ruby で作れる streamio-ffmpeg gem と AWS SQS をバックエンド基盤としたワーカー実装ができる Shoryuken gem の活用事例を中心に触れられていました。
リリース後の運用についても話されており、ECS の監視は Grafana を用いてリソース監視をしメモリ/CPU のスペック調整を行いながらコストを意識した運用を続けているとのことでした。
今後の展望として、パフォーマンスチューニングのために並列処理の最適化を進めていくことや、アップデート機能として長時間の動画アップロードやストリーミング配信を可能にできるようにしたいと話されており、ユーザーにとってよりメリットのある機能として作り上げていこうとする強い思い入れを感じました。
また、発表中には ffmpeg を使った動画変換のデモを挟んでおり、yumu さんが撮影した可愛いカピバラの動画をアップロードし動画変換された様子を紹介されていてたいへん和みました。
発表の最後では Shoryuken gem のリポジトリが先日アーカイブとなりショックを受けた話もされていましたが、その後 yumu さんご本人がメンテナの Pablo さんに連絡を取り、アーカイブが解除され yumu さんもメンテナのメンバーに加わるというとても素敵な Kaigi Effect があったことも後日観測しました! すごすぎる、おめでとうございます!
https://x.com/myumura3/status/1880872104775893101
https://x.com/myumura3/status/1884281861435974085
(桐生あんず)
moznion さんの発表内容は、Rails と Perl の違いを比較しながら、それぞれの特徴をもとにした開発スタイルに焦点を当てたものでした。 それらの違いを「Simple vs Easy」の構図で語っていた点が印象的です。
例えば、Rails は、規約があるフルスタックなフレームワークで Easy に作れる仕組みがある一方、隠蔽されている部分が複雑です。 一方で、Perl などの Simple 組み合わせでは、必要なものだけを組み込めたり、自分たちのベストプラクティスを作れたりする柔軟性があります。 とはいえ、Simple と Easy は完全に相反するものではないという点が重要なポイントです。
Rails と Perl などの Simple 組み合わせは、それぞれが Easy と Simple を両立しています。 Rails は、作るための仕組みは Easy ですが、ビジネスロジックは Simple に実現できます。 一方、Perl などの Simple 組み合わせは、最大公約数的な Easy ではなく、ドメインに特化した Easy を Simple とともに得られます。
私は Simple 組み合わせ村の経験はあまりありませんが、自社のドメイン知識をベースにシステムを考えていくことで、確かにドメインに特化した Easy と Simple が得られるのだろうと感じました。 逆に Rails は “Rails Way” という言葉があるように、最大公約数的な Easy と Simple を目指しているのだなという気づきも得られました。
特に印象的だったのは、「Simple 組み合わせでは自分たちに最適化したベストプラクティスを作れるので、レールを外れることを恐れなくて良くなる」という部分です。 Rails を書いている身としては、レールに沿っているかを気にする場面があるので、確かにと共感しました。 レールに沿ったものがベストプラクティスであるため、ベストプラクティスを考える手間はある程度省けており、ドメインロジックの実現に集中できるということなのだと思いました。
改めて Rails の立ち位置を考える機会となった発表でした!
The Rails Doctrine. もこちらの発表内容と合わせて読めるとより楽しめるかもしれませんね。
(dak2)
Ogawa さんは、Ruby DSL を使って PDF を生成するという内容でした。
PDF の仕様の話をすると、ヘッダー / ボディー / クロスリファレンステーブル / トレイラー の 4 つで構成されているようです。 その内、ボディー部のオブジェクトの構造は下記のようになっています。(一部省略)
1 0 obj << /Type /Catalog /Pages 2 0 R >> endobj
2 0 obj << /Type /Pages /Kids [ 3 0 R ] /Count 1 >> endobj
3 0 obj << /Type /Page /Parent 2 0 R /MediaBox [ 0 0 720 405 ]
/Resources 4 0 R /Contents 5 0 R >> endobj
...
xref
0 6
0000000000 65535 f
0000000009 00000 n
0000000058 00000 n
0000000115 00000 n
0000000227 00000 n
0000000319 00000 n
この構造を見ると、Catalog -> Pages <-> Page -> コンテンツストリーム という流れが見えてきます。 Catalog がエントリポイントとなり、Pages が描画するページを探し、Page で実際のコンテンツをたどる流れです。
また、数字の羅列はクロスリファレンステーブルというもので、ファイル内の各オブジェクトの位置を一覧化した情報です。
例えば 0000000009 00000 n
という記述は、「このオブジェクトは PDF ファイルの 9 バイト目にある」ということを示しています。
この情報があることで、PDF の任意のページにランダムアクセスが可能になります。もしこの情報がなければ、目的のページにアクセスするために 1 ページ目から順に読む必要があるでしょう。 しかし、人間がこの計算を行うのは難しいため、DSL 側でオフセット計算をしながら PDF を組み立てる仕組みになっていました。
class OffsetIO
attr_reader :offset
def initialize(io)
@io = io
@offset = 0
end
def <<(b)
@io << b
@offset += b.bytesize
end
end
code do
content <<~RUBY, style: JotPDF::Tokyork12::Highlighter::Ruby
def obj
@io << "obj "
yield
@io << " endobj"
end
RUBY
list x: 350, y: 150, size: 25, color: 0xffffff do
item "Ruby にはブロックがある"
end
end
紹介のあったコードの一部を抜粋しましたが、<<
メソッドを使ってクロスリファレンステーブルのバイトサイズを計算しつつ、content ブロック内で PDF の中身を組み立てる構造になっています。
ブロック構文を利用することで階層構造が視覚的に明確になり、code ブロックの中に content の内容や list の内容が含まれるという構図がわかりやすくなっています。
適度な粒度で抽象化されていく DSL の構築過程をとても楽しんで拝見しました。 業務で使っているツールなどをハックして再実装する試みは、そのツールとの機能差分を比較でき、より深い理解につながるので良いですよね! 私も何か Ruby で再実装できないかと考えさせられました。
さらに、発表のスライド自体もご自身が作った DSL で生成されていたというオチも素晴らしかったです (笑)
(dak2)
buty4649 さんの発表ではテキストフィルタツールのrf について紹介されました! rf は sed や awk、jq のようなテキストフィルターツールと同じように、テキストデータの加工や整形、抽出を効率的に行えるツールです。Ruby をインストールしていれば echo matz | ruby -p -e '$_.tr! "a-z", "A-Z"'
のようにワンライナーでテキストの変換を実行することもできますが、よりタイプ数を減らして簡単に使えるツールが欲しい!! とのことで rf を開発されたそうです。mruby を使ってワンバイナリーになっているので Ruby がなくてもインストールでき、Homebrew などのパッケージマネージャーにも対応されています。 brew install buty4649/tap/rf
でサクッとインストールできるので試してみてください!
rf では Ruby 実装を独自拡張しているところもあり、読み込んだ文字列を取得する $_
を _
で拡張してタイプ数を 1 文字減らしたり、変数を定義してなくても s+=1
のように加算代入できるようにしたりと、テキストフィルターだからこそ必要な機能やこだわりポイントが紹介されていて面白かったです! また、後半は mruby を使った CLI ツールの作り方も紹介してくださり、私自身 mruby を使ったことはなかったので学びが多かったです。
私も rf をインストールして使い始めましたがいいですね! rf /include/ app/controllers/xxx.rb
みたいに ruby で ruby のコードを探すのは気持ちいいです!! テキストフィルターしたいんだけど、awk とか grep とか毎回オプション忘れるし…正規表現の書き方も忘れるし…という方にはピッタリ合うツールだと思います!!
(三谷 昌平)
巨大な Rails アプリケーションである STORES における例外処理とエラー監視の整理について発表されました。
STORES の開発現場では、すべてのエラーを一括して処理する例外ハンドリングや、対応不要なエラーまでもがエラートラッカーにより通知されオオカミ少年化しているといった問題が発生していました。この状況を改善するためにチーム内で議論した結果、以下の 4 つの考え方に基づいて例外処理の整理を行なっていくこととなりました。
この考え方をもとに既存コードの改善が進められましたが、STORES では色々なチームの方が同じリポジトリにコミットするため、アナウンスだけではなかなか方針が浸透せず、修正前のコードを踏襲した新たなコードが増えてしまうという問題がありました。
そこで、RuboCop により、すべてのエラーを丸ごとハンドリングしてしまうコードや、Un Expected なエラーをハンドリングしてしまっているコードを取り締まるようにしました。これにより、同様の問題を抱えるコードの増加を防ぐことができ、既存の問題箇所は .rubocop_todo.yml にまとめられました。また、RuboCop 違反によって実装時に立ち止まって考えるタイミングを得られるようになったとのことです。
さらに、Expected なエラーであってもログに残すべきケースでは、エラートラッカーは使用せず、ログの用途に応じて適切な送り先を選択します。例えば、一定頻度以上で発生するエラーの検知には Datadog や New Relic などの APM を使用し、エラー発生後に処理が必要な場合にはデータベースや検索性の高いストレージに記録しているとのことです。
例外処理やエラー監視の混乱は、多くの開発現場で共通の課題です。本発表では、基本的な考え方から具体的な対応方法まで詳細に解説されており、開発に関わる多くの人にとって非常に有益な内容と感じました!
(chihaso)
RubyKaigi の NOC チームを長く担当されている花月かすみさんによる、DNS の暗号化の自動構成を行うためのプロトコルの紹介と、その検証のために QUIC ライブラリのラッパーを実装した、という話です。
Domain Name System(DNS) は最も身近にはドメイン名から IP アドレスを得るための方法として用いられていますが、実際にはドメイン名にあらゆるデータを紐付けられるキーバリューストア、階層型分散データベースとしてインターネットに欠かせない存在となっています。しかし DNS は一般に使われている方式 (UDP ポート 53(場合によっては TCP にフォールバック) でクエリを行う、通称「Do53」) では暗号化されておらず、カンファレンスのネットワークを含む公衆 WiFi では盗聴に対して脆弱であるということが知られています。カンファレンスにおいては WiFi どころかそのへんを転がしているケーブルに対して Man-in-the-Middle 攻撃することも容易です。そこで現代では DNS over TLS(DoT), DNS over HTTPS(DoH; この中には HTTP/2 を使うものと HTTP/3 を使うものがある), DNS over QUIC(DoQ) といった、クライアントとリゾルバ (※) の間の通信を暗号化することで盗聴に対して保護する方式が提案されています。
(※: 正確には RFC 9499 Section 6 でいう”Recursive Resolver”のこと。「フルサービスリゾルバー」、「キャッシュ DNS サーバー」と呼ばれることもある)
DNS の暗号化を行うにあたって、クライアントに対してこのサーバーは DNS クエリの暗号化に対応しています、という情報を伝えることで自動構成を行いたい、という要望があります。これを実現するために Adaptive DNS Discovery(ADD) というワーキンググループが IETF で活動しており、標準として提案されたプロトコルとして Discovery of Designated Resolvers(DDR; RFC 9462)、DHCP and Router Advertisement Options for the Discovery of Network-designated Resolvers (DNR; RFC 9463) があります。前者は macOS や iOS、後者は一部の Windows で使われているそうです。RubyKaigi 2023 以降では DoT, DoH, DDR を提供しており、だいたい半分くらいの DNS クエリが暗号化されていたそうです。
DNS は動作するプロトコルの組み合わせが非常に多く、また「少し壊れててもそれっぽく動いちゃう」ので、検証プログラムを実装することにしたそうです。Ruby で DNS over QUIC を検証するにあたって Ruby の QUIC 実装がほとんどなかったことから、ngtcp2 という C で書かれた QUIC 実装に Ruby バインディングを実装しました。この実装の工夫として、Ruby 本体で進行中の並行処理の機能に影響されないよう I/O まですべてを ngtcp2 に任せるのではなく I/O は Ruby で引き取るようにした、という点が挙げられていました。QUIC は通常の TCP ではカーネルが行う再送処理をアプリケーション側で巻き取ることで高速化を得ていますが、代わりにアプリケーションはその実装を頑張らなければいけないという性質があり、QUIC の約束する効率化を実現するためには単にラッパーを書くだけでは足りず考えることが多い、ということを実感できました。
なかなか Ruby の文脈でネットワークの裏側の話を聞くことがなかったのでとても新鮮でした。「動いて当たり前」と思われているネットワークの裏にこのような努力が埋まっているということを多くの人が感じていただければ、プロトコル実装仲間としてはとても嬉しいです。
(sylph01)
大倉さん (@okuramasafumi) 司会による、総勢 16 団体の東京圏を中心とする地域 rb コミュニティが集結したトークセッションとなりました。
Gotanda.rb, Shibuya.rb, Tokyu.rb, Omotesando.rb, Roppongi.rb, Sendagaya.rb, Ginza.rb, Shinjuku.rb, 中央総武.rb, mitaka.rb, Asakusa.rb, Nishinippori.rb, Urawa.rb, Saitama.rb, 柏.rb, しんめ.rb の実に 16 団体から登壇いただきます。意外、そして多彩、ご期待あれ!
東京 Ruby 会議 12 コンテンツ一覧|東京 Ruby 会議 12
最初の紹介パートでは、1 人 30 秒+スライド付きで各地域 rb の紹介が行われました。16 団体もいたこともあり、たくさんのコミュニティについて高速に触れられていく光景がちょっとシュールで楽しいひとときでした。
しかし、ここで各地域 rb の存在や活動内容を初めて知る方も多かったのではないでしょうか。聴衆の方々がこれを機に興味を持った地域コミュニティへと脚を運ぶ機会に繋がっていきそうに感じました。
紹介パートが終わってからは、事前に用意されたトークテーマ「今やっているコミュニティを主催するきっかけは?」「思い出に残っていることは?」「会場の参加者にメッセージ」についてその場で大倉さんの方から気になる内容を掘り下げつつ各地域 rb の方々がお答えしていくという座談会形式で行われました。
そこから出てくる話はどれも印象的な身の上話が多くコミュニティを作ることの楽しさが伝わるような内容が続きました。
その後の質疑応答パートや X の実況ハッシュタグ (#tokyorubykaigi) でも、この場に影響を受けてコミュニティの立ち上げや再興について機運を高める参加者が見受けられました。筆者自身もこの場に強く感化され新しく地域 rb を作ろうと思った 1 人です。
全体を通してとても和気藹々とした雰囲気で行われたトークセッションでした。会場に来れなかった方もぜひアーカイブ動画をご覧いただきその雰囲気を味わっていただきたいです!
(桐生あんず)
東京 Ruby 会議 12 では、一緒にお昼ご飯を食べる相手がいない筆者のような参加者に向けて、アンチボッチランチという企画が用意されました。 参加希望者は予約等なく当日集められ、ランダムな 3,4 人程度のグループに分けられてランチに送り出されました (グループ分けだけされて、あとはご自由にという感じ)。
筆者も初めてお会いする方々とランチをご一緒させていただきました。 道中一緒にプリクラを撮ったり、一人減ったと思ったらなぜか三人増えたり、お店がなかなか見つからなかったりといろんな事がありつつ、発表内容や普段の開発についてたくさんお話できて、とても楽しい時間を過ごす事ができました。
筆者は技術イベントが好きでよく参加はするものの、知らない人の中に入っていくのはなかなか難しく、他の参加者の方々との交流はあまりできていませんでした。 今回の企画は、筆者のような参加者には非常にありがたく、まさに地域 Ruby 会議らしい内容だったと感じました。
ご一緒させていただいた皆様、ありがとうございました!
(chihaso)
皆さんは物理カンファレンスに於いて重要視するのは何でしょうか。
トークでしょうか、トークでしょうね、トークだと思うんですが、そうではない人もいます。例えばそう、トークの最重要人物、スピーカーのひとびとですね。スピーカーのひとびとは、いま準備しているスライドで十分に伝わるか、きちんと人前で話せるか、時間配分は大丈夫か、とたくさんのことを考えて緊張していることが大半かと思います。スポンサーのひとびとは、自らのブースでどれくらいの人がどれくらい興味を持ってくれるだろうか、採用につながると嬉しいな、と考えて参加すると思います。それからオーガナイザーや当日スタッフのひとびとは、運営の様々なことを考えながら、ひとびとが楽しめるよう動いていると思います。
わたしはスポンサーブースの担当者を除く、参加者・スピーカー・当日スタッフ・オーガナイザーの各ロールで物理カンファレンスに参加したことがあります。スピーカーとして参加した時は、喋り始める直前に体が冷えて緊張に染まっていましたし、当日スタッフとして走り回るときはひとびとの導線を整理し続けていましたし、オーガナイザーとしてひとびとを迎え入れる際には、裏側で当日発生する「これどうしよう!」の対応をしたりしていました。一般参加者として参加するときは、たくさんの人と出会い、いろんな話をしていました。
Rubyist となって 10 年とちょっと、わたしがカンファレンスに於いて重要視するポイントは、「誰が参加していて、誰と話せるのか」になりました。誰が何を喋るのか、どこがスポンサーブースを出すのか等の一切合切を考えずに「誰が行くんだろう」がメインです。カンファレンスに於いて、人と会うこと、人と喋ること、人と知り合うことがわたしにとってのすべてです。東京 Ruby 会議 12 は、「誰が参加していて、誰と話せるのか」という視点に於いて期待値が高くありました。オーガナイザーチームの面々が主催するイベントで集まるひとびとは、きっと楽しく話せるであろう、あの人も来るかな、あの人は会えるかな、そんな期待とともに参加した東京 Ruby 会議 12 でした。
わたしは顔見知りから友人まで幅広く「あけましておめでとうございます。今年もよろしくお願いします」という切り口とともに沢山の話をしました。トークは基調講演をちらっと見たくらいで、ほとんどの時間を廊下で過ごしていました。スポンサーブースの中の人と話し込む時間もあれば、その場で話し込むことも、ホワイトボードを切欠に人と話すこともありました。ホワイトボードを中心に改行の話を始めるパーサー (に特に興味のある Rubyist) のひとびとを見てオーガナイザーのいかるがくんが「うわギャングだ」と称していたのをよく覚えています。(パーサーの人々はパーサーギャングと呼ばれています)
ひとびとと会う機会は、食事会や勉強会といった形で作れますが、カンファレンスは殊更特別です。平日夜の勉強会の参加は難しい、食事は家族と摂ることにしているなど、様々な制約があるひとびとがドンと集まるのです。たいていの友達には会えるし、友達の友達とも知り合える、限りなく身内的な閉じた空間でもあり、初めましての人とも出会える、開けた場所でもあるのです。
Rubyist が一堂に会す機会は、RubyKaigi や地方 Ruby 会議など様々がありますが、東京 Ruby 会議 12 も同じく Rubyist が集う場だったかと思います。
皆さんは、誰とどんな話をしましたか?
(sakahukamaki)