XP祭り 2021に登壇します

今週末の 2020年9月18日(土) に開催される、XP祭り 2021 で『ソフトウェア見積りの公式』というタイトルで登壇します。

私の登壇は 15:00-15:45 の I Hall です。

https://confengine.com/conferences/xp2021/schedule

eXtreme Programming のカンファレンスということで、eXtreme Programming を背景にしたソフトウェア見積りの話をします。インターネットに繋がっていれば参加できる、無料のオンラインカンファレンスなので、よければ遊びに来てください。

xpjug.connpass.com

また当日は勤務先から8人が登壇します。以下のエントリをあわせてどうぞ。

blog.agile.esm.co.jp

RubyKaigi Takeout 2021に登壇した

RubyKaigi Takeout 2021 に登壇した。

rubykaigi.org

まず最初に。@yahonda さんには、昨年に引き続き事前に英文や構成レビューをしていただきました。多忙のおり、丁寧に見ていただいて本当にありがとうございました。

当日のスライドは以下です。

講演内容について、当初は6つのパートがありセルフレビューでパートをひとつ削って5つのパートで構成していました。その後、@yahonda さんにレビューしてもらった際にストーリ展開の都合でさらにパートをさらにひとつ削ることになり、最終的には講演時の4つのパート構成としたのがリリース版です。フルレンスでの完全版としては世に出すことはないと思うのですが、削ったパート分はどこかで独立したショートトークみたいに使ったりするかもしれません。

登壇について今年は収録と生配信のいずれかを選択できるようになっていましたが、私は昨年の実績ベースで収録という形でのセッションとしました。前年と比べて意識していたのは、事前にタイムテーブルが公開されていたので、収録時にややタイムテーブルを意識したトークを入れたりしてみることで、ライブ感を足せないかというのが小さなひとつの試みとしていました。例えば、他の開発ツールのトークについて少し話題を入れてみたり、裏番組になっていた Jeremy Evans さんが執筆した『Polished Ruby Programming』の中で RuboCop について言及していたので、本編でも触れてみたりといった感じです。本編でも話した RuboCop 導入の戦略のひとつについて Jeremy さんは丁寧に著書の中で説明しているので、そちらもひとつの参考ケースになると思います。

あと、rubocop/rubocop#10000 の PR は間に合ったらトークに含めようと温めていたネタでした (開発者も人間なので、そういった遊び心的なものを持ちながらやっているのが伝わったかな?) 。これの元ネタは kamipo さんによる rails/rails#30000 で、せっかくのキリ番ならコンテンツ性のある PR にしたいというものを形にしたものです。本編で取りあげた rubocop-daemon の統合的なものはさすがに間に合わないので、だいたいのユーザーにとっては益になりそうな、デフォルト並列化を 10000 番ネタにしました。

github.com

登壇が終わっての一番としては、RubyKaigi オーガナイザーチームのみなさんにはトラブル対応の中での配信をして頂き、本当にありがとうございました。また予期しないトラブルの中でも、視聴者のチャット欄は MINASWAN なコメントで間が保たれていて Ruby コミュニティの練度の高さ、自分な好きなコミュニティを再確認できたりしました。

楽しかったです。ありがとうございました & 初日お疲れ様でした!

2021年9月14日追記

さっそく当日の動画が公開されていました。ありがとうございます。

www.youtube.com

f:id:koic:20210909191444p:plain

社内向けに「dRubyによる分散オブジェクトプログラミング勉強会 」を行った

6年くらい前に浜松Ruby会議01でLT登壇した内容を、当時と組織メンバーの顔ぶれも変わっていることもあり社内向けに話した。

www.slideshare.net

現在 @9sako6 がすすめている PofEAA の社内読書会で登場する RPC や RMI, CORBA といった分散システムに関する語彙について、それらがどういったものか道具箱にイメージが増えると良さそうと思ったのがきっかけ。

Ruby で分散オブジェクトプログラミングをする場合には、dRuby というカッコいい標準ライブラリがあるので、そちらを題材のサンプルにしていた。実際のところ dRuby には現職で2度窮地を救われたことがあったので、そのあたりのエピソードを交えつつ話していた (いちおう記しておくと Rails アプリケーション開発での事例ではない) 。

dRuby による分散・Web プログラミングについて詳しく学びたい方は、dRuby 作者の咳さん自身による以下の書籍がおすすめです。

最後にネタ元となる最初の dRuby が記された URL を貼っておきます。

blade.nagaokaut.ac.jp

guard-rubocop 1.5.0 をリリースした

guard-rubocop 1.5.0 をリリースした。RuboCop の GitHub Discussions に投稿されたのがはじまり。

実質的にリリースした機能は以下。

github.com

RuboCop 実行に対するコマンドが rubocop 固定だったものを、cmd オプションを使うことで bin スタブの bin/rubocop に外から切り替えたりできるようにしたいといったもので、bundle exec spring binstub rubocop なんかで Spring を有効にした状態で実行可能にしたいようだった。

そのほかにもコマンドの差し替えを可能にすることで、以下のようなパイプを使った結果の RuboCop 実行など、利用者にとって有用そうな機能だった。

guard :rubocop, cmd: "git ls-files -m | xargs ls -1 2>/dev/null | grep '\.rb$' | xargs bin/rubocop" do
  watch(%r{.+\.rb$})
  watch(%r{(?:.+/)?\.rubocop(?:_todo)?\.yml$}) { |m| File.dirname(m[0]) }
end

余談ですが、guard-rubocop は yujinakayama さんが開発していたものを RuboCop HQ に移管して、コアの方でメンテナンスできるようにしていた流れからの、今回のリリースとなっています。ユーザーの方はアップデートしてみてください。

Rails/OSSパッチ会 2021年8月

Rails/OSS パッチ会だった。オンライン開催になって、それなりに回数も経ってきたところ。

自分は仕事で bin/rails db:schema:load の実行が遅いのが気にかかっていて、結構前に手元で試していた高速化のアイデアについて話したりしていた。

bin/rails db:schema:load は内部的に db/schema.rb を load しているだけなのでリニアに実行される。

そこで、ひとつの高速化アイデアとしてのキーワードは「並列化」。db/schema.rb のうち create_table do ... end, add_foreign_key のコードをそれぞれコレクションにして、1. create_table のコレクションを (Parallel gem なんかで) パラレル実行、2. add_foreign_key のコレクションをパラレル実行、最後に ActiveRecord::Schema.define を実行するとかどうだろうというものだった。

手元にあるアプリケーションへのモンキーパッチによる PoC だと、前段のコレクションに詰める仕込み部分で db/schema.rb を RuboCop を使って AST プログラミングするという異能を使っている (のでこれで upstream に送ることはない) が、そこはさすがに method_missing とか使うとかした方が良いだろうなどコメントをもらいながら話していた。

さらにその先の結論としては、MySQL なんかでの bin/rails db:schema:load はそんなに遅くないらしく、どうも Oracle adapter のスキーマ処理まわりにボトルネックがありそうで、そちらを解決した方が良さそうというオチだった。まあ、そうですよね。

次回の Rails/OSS パッチ会は 2021年9月30日(木) 17:00-19:00 です。

RubyKaigi Takeout 2021 に登壇します

RubyKaigi Takeout 2021 に『RuboCop in 2021: Stable and Beyond』というタイトルで登壇します。

私の登壇は1日目である 2020年9月9日(木) の 11:30-11:55 です。

rubykaigi.org

前回の RubyKaigi Takeout 2020 での講演が RuboCop 1.0 リリース前の道のりだったことに対して、今回は RuboCop 1.0 リリース後の動きと今後に向けたトピックでまとめています (絶賛準備中) 。開発の舞台裏についても少し取りあげる予定なので、人によっては OSS 開発環境の参考になったりするかもしれません。よければテイクアウトしに来てください。

DatabaseCleanerを使ったテストを倍速にした設定の見直し

はじめに

テストのデータベースクリーニングをする gem としては、DatabaseCleaner と DatabaseRewinder がメジャーどころとしてあります。

github.com

github.com

今回は DatabaseCleaner の話です。

クリーニング戦略を切り替えて計測する

DatabaseCleaner では transaction, deletion, truncation といったデータベースのクリーニング戦略があり、E2E での非同期 UI 系のテストでは transaction 以外を選択することになると思います。

早速結論ですが、非同期 UI 系のスローテストについて truncation から deletion に変えたところ 60 分の CI が 30 分になりました。

     if example.metadata[:javascript]
-      DatabaseCleaner.strategy = :truncation, {except: MASTERS}
+      DatabaseCleaner.strategy = :deletion, {except: MASTERS}
     else
       DatabaseCleaner.strategy = :transaction
     end

RDBMS によると思うのですが、truncation は (deletion に比して) 概ね固定された実行効率であることに対して、deletion はデータ量に依存したり変動要素が多いようです。 そしてこれらは、どちらが優れているというものではなくコンテキストによって選択されることになります。

詳しくは DatabaseCleaner から参照されている Stack Overflow の記事を参照してください。

stackoverflow.com

テスト時では閾値とを INSERT するデータ量を小さくするなどの定石があったりするため、テストの作りや RDBMS によって deletion の方が速いことがあるというのはなるほどというものでした。長年開発を続けてスキーマやデータが変遷しているようなアプリケーションは一度計測し直してみて良いかもしれません。

まとめ

実際のところ、どちらが速いというよりはコンテキストによるようなので、テストが遅いなあと思ったら、戦略を切り替えてみるとテストが速くなることがあるかもしれません (し遅くなるかもしれません) 。CI の結果を計測してみましょう。

マジかというものですが、事実のみを示す数字によるとデータベースクリーニングで 30 分くらい余計にかかっていたわけでした。

最後に過去発表した関連スライドのページをのせておきます。

www.slideshare.net

今日はここまでです。ハックを続けましょう。