Upgrade to Pro — share decks privately, control downloads, hide ads and more …

技術的負債の借り換え on Ruby and Rails update

ginkouno
November 05, 2023

技術的負債の借り換え on Ruby and Rails update

https://kaigionrails.org/2023/talks/ginkouno/
Kaigi on Rails 2023登壇時の資料です。

ginkouno

November 05, 2023
Tweet

More Decks by ginkouno

Other Decks in Programming

Transcript

  1. 永久保存版Railsアップデートガイド 永久保存版!?伊藤さん式・Railsアプリのアップグレード手順 ”Rails 以 外 のgemを 全 部 最 新

    にする Railsのアップデートに引きずられて他のgemも上げることが多いので、先にRails以外のgemを最新にして おくとRailsアップデート後に不具合が起きた時に切り分けがしやすいです。 ” ”コラム:gemは普段からこまめにバージョンアップしよう gemのバージョンアップ作業は実際にやってみると、かなり骨が折れると思います。 古いバージョンのgemが多ければ多いほど、この作業のしんどさが増えるので、日頃からこまめにgemを最 新版にアップデートしていくことをお勧めします。”
  2. Rails、RubyのEOL 着手 gem update その1 gem update その2 gem update

    その3 gem update その4 想定される事態
  3. 6 5 4 3 2 1 ウ◯ジマ くん ミ◯ミの 銀次

    ほのぼの 約束 銀行 カーローン 住宅 ローン 完済 10日で5割 10日で1割 年4.0%〜     18.0% 年0.85%〜     3.5% 0.319%〜     1.58% 0% 世間の金利の例
  4. 6 5 4 3 2 1 ウ◯ジマ くん ミ◯ミの 銀次

    ほのぼの 約束 銀行 カーローン 住宅 ローン 完済 10日で5割 10日で1割 年4.0%〜     18.0% 年0.85%〜     3.5% 0.319%〜     1.58% 0% 世間の金利の例 EOL超過はこの辺
  5. 6 5 4 3 2 1 ウ◯ジマ くん ミ◯ミの 銀次

    ほのぼの 約束 銀行 カーローン 住宅 ローン 完済 10日で5割 10日で1割 年4.0%〜     18.0% 年0.85%〜     3.5% 0.319%〜     1.58% 0% 世間の金利の例 EOL超過はこの辺 こっちに借り換え
  6. Rails、RubyのEOL 着手 gem update その1 gem update その2 gem update

    その3 gem update その4 完済まで至らずとも、借り換え手数料 = 工数 をあまりかけずに 利率の低い負債に借り換えたい
  7. def self.up set_table_comment :table_name, "A table comment" set_column_comment :table_name, :column_name,

    "A column comment" end def self.create_table :table_name, :comment => "A table comment" do |t| t.string :column_name, :comment => "A column comment" end • Rails5.0から同様の機能が搭載されはじめ、5.1で十分な機能に • migration_comments gemの最後のcommitは7年前 • Rails6.1では動かない migrationでコメントをつけることができる
  8. 対策案 ・Rails6.1で使えるようにforkしてcommitを積む  ← もうほかの利用者も居なそう、メンテコスト増 ・migration fileをRails標準機能利用に書き換える  ← migration fileが1540、書き換え箇所が580で少々怖い ・この際RidgePoleに移行して圧縮する

     ← 個人的には好みだけど依存するgemの増加を懸念する意見 ・wrapperとなるmethodを作り、migration_commentsを利用停止  ← code少量、標準機能使うしメンテコスト小【採用】
  9. wrapperとなるmethodを作る(1) migration_commentsのmethodを呼ぶと、 標準のRailsの機能が呼ばれるようにする(set、remove) module ActiveRecord class Migration def set_column_comment(table_name, column_name,

    comment) change_column_comment(table_name, column_name, comment) end def remove_column_comment(table_name, column_name) change_column_comment(table_name, column_name, nil) end # 以下略
  10. 動作確認 改修前とtable構造に変化がないか、 table schema同士のdumpを比較して確認する % mysql -u root --no-data co_development

    > schema_without_migration_comments % diff schema_with_migration_comments schema_without_migration_comments c12177c12177 < -- Dump completed on 2023-02-14 16:08:03 --- > -- Dump completed on 2023-02-14 17:05:28
  11. CI監視 migration_commentsのmethodが新しく呼ばれないよう、 CIで監視する #!/bin/bash if find/db/migrate | sort | awk

    -F/ ‘int($3) > 2023213000000’ | xargs grep -Hn ‘set_column_comment\|set_table_comment\|remove_column_comment\|remove_table_comm ent\|t\.column’; then echo “migration_comments gemのmethodを使わず、Railsが提供するmethodを利用して 下さい” exit 1 fi
  12. 6 5 4 3 2 1 ウ◯ジマ くん ミ◯ミの 銀次

    ほのぼの 約束 銀行 カーローン 住宅 ローン 完済 10日で5割 10日で1割 年4.0%〜     18.0% 年0.85%〜     3.5% 0.319%〜     1.58% 0% Rails6.1に Updateできない状態
  13. 6 5 4 3 2 1 ウ◯ジマ くん ミ◯ミの 銀次

    ほのぼの 約束 銀行 カーローン 住宅 ローン 完済 10日で5割 10日で1割 年4.0%〜     18.0% 年0.85%〜     3.5% 0.319%〜     1.58% 0% Rails6.1に Updateできない状態 Rails6.1にUpdate可能 Rails標準機能利用 + 少量のcode
  14. 6 5 4 3 2 1 ウ◯ジマ くん ミ◯ミの 銀次

    ほのぼの 約束 銀行 カーローン 住宅 ローン 完済 10日で5割 10日で1割 年4.0%〜     18.0% 年0.85%〜     3.5% 0.319%〜     1.58% 0% Rails6.1に Updateできない状態 Rails6.1にUpdate可能 Rails標準機能利用 + 少量のcode みなさん的には何番でしょう?
  15. 複数DBに対応できるgem Book.with_readonly { Book.first } # replica dbから読む Book.with_readonly do

    author = Book.first.authors.first # replica dbから読む author.family_name = 'new_family_name' Author.with_writable do author.save! # primary dbに書く end end
  16. Ruby on Rails Guidesの指示通りにdatabase.ymlを書き換える database.ymlの修正 production: primary: database: my_database username:

    root password: <%= ENV['ROOT_PASSWORD'] %> adapter: mysql2 primary_replica: database: my_database username: root_readonly password: <%= ENV['ROOT_READONLY_PASSWORD'] %> adapter: mysql2   replica: true
  17. wrapperとなるmethodを作る switch_pointと同名のwrapper methodを作り、Rails標準のmethodを呼ぶ class ApplicationRecord < ActiveRecord::Base self.abstract_class = true

    connects_to database: { writing: :primary, reading: :primary_replica } def self.with_readonly(&block) ActiveRecord::Base.connected_to(role: :reading, &block) end end
  18. 動作確認 docker containerを複数立ち上げてそれぞれのquery logを監視 read / writeが各dbに対しSQLが意図通り振り分けられ発行されるか確認 services: primary_mysql: build:

    ./mysql/primary container_name: ‘primary_mysql’ ports:    -“3306:3306” replica_mysql: build: ./mysql/replica container_name: ‘replica_mysql’ ports: - “3307:3306”
  19. 6 5 4 3 2 1 ウ◯ジマ くん ミ◯ミの 銀次

    ほのぼの 約束 銀行 カーローン 住宅 ローン 完済 10日で5割 10日で1割 年4.0%〜     18.0% 年0.85%〜     3.5% 0.319%〜     1.58% 0% Rails6.1に Updateできない状態
  20. 6 5 4 3 2 1 ウ◯ジマ くん ミ◯ミの 銀次

    ほのぼの 約束 銀行 カーローン 住宅 ローン 完済 10日で5割 10日で1割 年4.0%〜     18.0% 年0.85%〜     3.5% 0.319%〜     1.58% 0% Rails6.1に Updateできない状態 Rails6.1にUpdate可能 Rails標準機能利用 + 少量のcode
  21. 6 5 4 3 2 1 ウ◯ジマ くん ミ◯ミの 銀次

    ほのぼの 約束 銀行 カーローン 住宅 ローン 完済 10日で5割 10日で1割 年4.0%〜     18.0% 年0.85%〜     3.5% 0.319%〜     1.58% 0% Rails6.1に Updateできない状態 みなさん的には何番でしょう? Rails6.1にUpdate可能 Rails標準機能利用 + 少量のcode
  22. sidekiqのふつうの使い方 class MessageJob include Sidekiq::Job def perform(article_id, message) Message.create!(article_id: article_id,

    message: message) end end MessageJob.new.perform_async(article_id, “hello”) Jobを作る 呼び出す
  23. 任意のmethodを受け取る仕組みを作る ・WrapperClassのinstanceは、初期化時にClass名を取得 ・method_missingでmethod名、引数を取得、YAML Dumpして共通Jobに渡す class DelayWrapper < DelayWrapperBase def initialize(klass,

    **sidekiq_option) @class_name = klass.to_s @sidekiq_option = sidekiq_option end def method_missing(method_name, *args, **kwargs, &block) CommonJob .set(@sidekiq_option) .perform_async(args_yaml(method_name, args,kwargs)) end end
  24. 共通Jobが任意のmethodを実行 ・渡されたClass名、method名、引数を復元し実行 class CommonJob include Sidekiq::Job def perform(args_yaml) klass, method_name,

    args = ::YAML.load(args_yaml) kwargs = args.list.is_a?(Hash) ? args.pop : {} if klass.ancestors.include?(ActionMailer::Base) klass.public_send(method_name, *args, **kwargs).deliver_now else klass.public.send(method_name, *args, **kwargs)   end end end
  25. 6 5 4 3 2 1 ウ◯ジマ くん ミ◯ミの 銀次

    ほのぼの 約束 銀行 カーローン 住宅 ローン 完済 10日で5割 10日で1割 年4.0%〜     18.0% 年0.85%〜     3.5% 0.319%〜     1.58% 0% Ruby3.0に Updateできない状態
  26. 6 5 4 3 2 1 ウ◯ジマ くん ミ◯ミの 銀次

    ほのぼの 約束 銀行 カーローン 住宅 ローン 完済 10日で5割 10日で1割 年4.0%〜     18.0% 年0.85%〜     3.5% 0.319%〜     1.58% 0% Ruby3.0に Updateできない状態 Ruby3.0にUpdate可能な状態 自前codeだが将来的に使えなくなる可能性
  27. 6 5 4 3 2 1 ウ◯ジマ くん ミ◯ミの 銀次

    ほのぼの 約束 銀行 カーローン 住宅 ローン 完済 10日で5割 10日で1割 年4.0%〜     18.0% 年0.85%〜     3.5% 0.319%〜     1.58% 0% Ruby3.0に Updateできない状態 Ruby3.0にUpdate可能な状態 自前codeだが将来的に使えなくなる可能性 みなさん的には何番でしょう?