- 開発
週刊Railsウォッチ(20190917-1/2前編)Sidekiq 6.0がリリース、銀座Rails#13と「出張!Railsウォッチ」、るびま0060号、ロックイン回避の落とし穴ほか
こんにちは、hachi8833です。
- 各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
- 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄
- 毎月第一木曜日に「公開つっつき会」を開催しています: お気軽にご応募ください
⚓週刊Railsウォッチ「公開つっつき会」第15回のお知らせ(無料)
第15回目公開つっつき会は、10月5日(木)19:30〜にBPS会議スペースにて開催されます。皆さまのお気軽なご参加をお待ちしております🙇。
⚓Rails: 先週の改修(Rails公式ニュースより)
公式の更新情報がなかったので、今回も6-0-stableを中心に見繕いました。
⚓(6.0)insert allなどでクエリキャッシュをクリアするようにした
insert
、insert_all
、upsert
、upsert_all
ではクエリキャッシュをクリアするようになった。
Eugene Kenny
changelogより
# activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb#L154
+ def exec_insert_all(sql, name) # :nodoc:
+ exec_query(sql, name)
+ end
# activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb#L9
def included(base) #:nodoc:
dirties_query_cache base, :insert, :update, :delete, :truncate, :truncate_tables,
- :rollback_to_savepoint, :rollback_db_transaction
+ :rollback_to_savepoint, :rollback_db_transaction, :exec_insert_all
base.set_callback :checkout, :after, :configure_query_cache!
base.set_callback :checkin, :after, :disable_query_cache!
end
# activerecord/lib/active_record/insert_all.rb#L23
def execute
message = +"#{model} "
message << "Bulk " if inserts.many?
message << (on_duplicate == :update ? "Upsert" : "Insert")
- connection.exec_query to_sql, message
+ connection.exec_insert_all to_sql, message
end
つっつきボイス:「#37142 のupsert_all
のバグIssue↓に対する修正対応という感じですね」
# 37142より
ActiveRecord::Base.connection.enable_query_cache!
#=> true
User.create(name: "Fred")
#=> #<User id: 1, name: "Fred", created_at: "2019-09-06 02:24:38", updated_at: "2019-09-06 02:24:38">
u = User.first # ここでクエリキャッシュができる
#=> #<User id: 1, name: "Fred", created_at: "2019-09-06 02:24:38", updated_at: "2019-09-06 02:24:38">
User.upsert_all([{id: u.id, name: "Amy", created_at: u.created_at, updated_at: Time.now}])
#=> #<ActiveRecord::Result:0x00007f9b16b439e0 @columns=[], @rows=[], @hash_rows=nil, @column_types={}>
User.first.inspect
#=> #<User id: 1, name: "Fred", created_at: "2019-09-06 02:24:38", updated_at: "2019-09
再現手順を実行するとActive Recordがクエリキャッシュを読み込むため古い結果が返され、クエリが発生しない。このクエリキャッシュはdatabase_statementsでクエリが変更された場合に自動的にデータのキャッシュをクリアするようセットアップされるが、新しいupsert/insert系メソッドではそうなっていない。
#37142より大意
⚓(6.0)エンドレスRangeでinclude?
を呼ぶと落ちる問題を修正
# activesupport/lib/active_support/core_ext/range/include_time_with_zone.rb#L11
def include?(value)
- if first.is_a?(TimeWithZone)
+ if self.begin.is_a?(TimeWithZone)
cover?(value)
- elsif last.is_a?(TimeWithZone)
+ elsif self.end.is_a?(TimeWithZone)
cover?(value)
else
super
end
end
つっつきボイス:「endless Rangeでは #first
/ #last
ではなく #begin
/ #end
を使うべきという話みたいなのだけど、この辺のドキュメント、Rubyの日本語リファレンスマニュアルの方だと違いが書かれていなくて、英語のRDocの方には書かれているという差があるみたい」「😳」
後で見てみると、日本語リファレンスマニュアルにはendless Rangeについての記述自体がありませんでした。
Ruby 2.6.4のPryでやってみると↓、エンドレスRangeのlast
はエラーになり、end
だとエラーになりませんでした。なお...
でも同じです。
» (1..).last
RangeError: cannot get the last element of endless range
from (pry):24:in `last'
» (1..).end
»
⚓(6.0、5.2.3)app/にREADME.mdを置くとdevelopment環境でエラーになる問題を修正
# railties/lib/rails/application.rb#L350
def watchable_args #:nodoc:
files, dirs = config.watchable_files.dup, config.watchable_dirs.dup
ActiveSupport::Dependencies.autoload_paths.each do |path|
- dirs[path.to_s] = [:rb]
+ File.file?(path) ? files << path.to_s : dirs[path.to_s] = [:rb]
end
つっつきボイス:「6.0と5.2.3のLinuxのdevelopment環境の場合に起きたそうです」「autoload_paths
にディレクトリパスではなくファイルパスを書いているとダメだったのを、ファイルパスでも正常に動くようにした模様」
⚓(master)classやmoduleもActiveJobの#perform
引数に渡せるようにした
# activejob/lib/active_job/serializers/module_serializer.rb
+# frozen_string_literal: true
+
+module ActiveJob
+ module Serializers
+ class ModuleSerializer < ObjectSerializer # :nodoc:
+ def serialize(constant)
+ super("value" => constant.name)
+ end
+
+ def deserialize(hash)
+ hash["value"].constantize
+ end
+
+ private
+ def klass
+ Module
+ end
+ end
+ end
+end
つっつきボイス:「Factory method的なクラスをActiveJobのperform時に渡せるようになった、という感じのようだ」
# 同PRより
class EmailJob < ApplicationJob
queue_as :default
def perform(template_class, *arguments)
template_class.new(*arguments).send!
end
end
module Email
class FooTemplate ... end
class BarTemplate ... end
end
EmailJob.perform_later(Email::FooTemplate, ...)
EmailJob.perform_later(Email::BarTemplate, ...)
参考: Factory Method パターン - Wikipedia
⚓(master)Rubyのキーワード引数変更に引き続き対応
- commit: Unify `add_column` method definition with other ones that take keywor… · rails/rails@70afbf2
先週(ウォッチ20190909)に続くキーワード引数周りの対応です。
# activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb#L480
- def add_column(name, type, options)
+ def add_column(name, type, **options)
name = name.to_s
type = type.to_sym
@adds << AddColumnDefinition.new(@td.new_column_definition(name, type, **options))
end
end
# activerecord/lib/active_record/migration/compatibility.rb#L153
- def add_column(table_name, column_name, type, options = {})
+ def add_column(table_name, column_name, type, **options)
if type == :primary_key
type = :integer
options[:primary_key] = true
end
super
end
⚓Rails
⚓Sidekiq 6.0がリリース(Ruby Weeklyより)
- 元記事: Welcome to Sidekiq 6.0
- サイト: Sidekiq
sidekiq.orgより(CC BY-SA 4.0)
「デーモン化をやめた」「ログ出力を一新」「Active Jobとの統合」が目に付きました。
つっつきボイス:「利用側としてはログフォーマッタが使えるようになったというくらいかな?: sidekiqctlバイナリがなくなった、とかも書いてあるので、セットアップスクリプト周りはプロジェクトによっては変更の必要があるのかもしれない」「おぉ」「公式のUpgrade noteの方が情報量ありそう↓」
以下は同アップグレードノートより:
ActiveJobで
sidekiq_options
を用いてSidekiqの機能や内部を直接設定できるようになった(retryサブシステムなど)。ActiveJobでうまく動かない一部の機能(unique jobなど)についてはネイティブのSidekiq::Worker
APIが望ましい。
class MyJob < ActiveJob::Base
queue_as :myqueue
sidekiq_options retry: 10, backtrace: 20
def perform(...)
end
end
- ログ出力が再設計されてフォーマッターやSidekiq付属のフォーマッタをpluggableにできるようになった
- default: macOSの典型的な出力
- heroku: Heroku実行時に特化した出力
- json: インデックス検索用のJSONフォーマット(1行1ハッシュ)
- 検出された環境に最適なフォーマッターが有効になる。明示的にログフォーマッターを設定することでオーバーライドもできる。詳しくはLogging Wiki参照。
Sidekiq.configure_server do |config|
config.log_formatter = AcmeCorp::PlainLogFormatter.new
# config.log_formatter = Sidekiq::Logger::Formatters::JSON.new
end
- 以下を廃止: デーモン化、logfileやpidfileコマンド引数、
sidekiqctl
バイナリREDIS_PROVIDER
変数は正しく使うこと- デフォルトのシャットダウン時間を8秒から25秒に延長
- 以下はサポート対象外:
- Rails 5より前
- Ruby 2.5より前
- Redis 4より前
- Rails 6以降はZeitwerkモードでのみ動作する
⚓Stimulusjsってどう?
- ハンドブック: Stimulus Handbook: The Origin of Stimulus
- リポジトリ: stimulusjs/stimulus: A modest JavaScript framework for the HTML you already have
Stimulusjsのリポジトリは★7500超えで、issueやPRがほぼ残っていないのがびっくりです。
While I don't like to pile on with simply another "here's how I did it", but I recently built a #stimulusjs implementation of working with what I called "checkbox families" where define different kinds of behaviors for inter-dependent nested checkboxes: https://t.co/QAQuXj8tbT
— Stephen Margheim (@fractaledmind) August 29, 2019
- 元記事: Sprinkling StimulusJS - Light JS Without Heavy Choices. - DEV Community 💻💻
- Reddit: Why is Stimulusjs not popular? : javascript -- 「Stumulusjsが人気ないのはなぜ?」
- 元記事: Stimulus Handbookを大体やったので所感を書く - patorashのブログ
- 元記事: STIMULUSでちょっとリッチなUI - ハマログ
-
サンプルサイト情報: Post your examples or open source projects - Links - Stimulus Discourse(ログイン必要)
つっつきボイス:「StumulusjsはBasecampが作っていてRailsとの相性がよさそうなのが気になったので」「フロントエンドも全部Railsエンジニアが書くならStumulusjsは悪くない選択肢にも見えるけど、Railsエンジニアってフロントエンドは触りたくないと言っている人もちらほら見る(そもそもサーバーサイドで手一杯で手が回らないという話も)ので、潤沢なRailsエンジニアの供給を前提とするのが果たして妥当かどうか、という話になるのかもしれないですね」
⚓Rails 6ではDBのadvisory lockを無効にできる(RubyFlowより)
Rails 6ではdatabase.ymlでadvisory lockをオンオフできるそうです(デフォルトはtrue)。
production:
adapter: postgresql
advisory_locks: false
つっつきボイス:「migrationの時だけ参照される?ような説明になっているように見える: 無効にしたいシチュエーションがよくわからない🤔」
参考: 13.3. 明示的ロック -- Advisory lockは「勧告的ロック」と訳されてます
参考: 3.19 接続設定 -- Rails アプリケーションを設定する - Rails ガイド -- advisory_locks
設定の説明
「ガイドによると、PostgreSQLのPgBouncer↓とかを使う時にもadvisory lockをオフにする必要があるかもしれないってありますね」
参考: PgBouncer - lightweight connection pooler for PostgreSQL
⚓銀座Rails#13で「出張!Railsウォッチ」
9/12の銀座Rails#13でmorimorihogeさんが「出張!Railsウォッチ」で登壇しました。お題はRails 6のAction Textです。
本日の発表スライドを公開しました。Rails6で新しく入ったAction Textについてがメインです:出張!Railsウォッチ in 銀座Rails#13 https://t.co/ywwgeamZSI #ginzarails
— Masato Mori (@morimorihoge) September 12, 2019
以下のスライドではTechRachoの翻訳記事「ActiveRecord::FixtureSet
」にも言及いただきました🙇。
先程の発表資料です / Rails Fixtures再考 - Speaker Deck https://t.co/Pz4iCWMWp4 #ginzarails
— masa寿司 (@masa_iwasaki) September 12, 2019
発表資料です。本日(昨日)はありがとうございました。#ginzarails https://t.co/fzZIDKfTAj
— 🐈@充電中 (@neko314_) September 12, 2019
明日の銀座Rails 1周年記念回で、Railsのパフォーマンスに関するちょっとマニアックかも知れないお話をします。先ほど席を増やしてもらったので、今からご登録いただいてもまだ間に合うかもしれません。
興味のある方とか銀座で飲みたい方はぜひどうぞ! https://t.co/RqTvJD45lV— Akira Matsuda (@a_matsuda) September 11, 2019
つっつきボイス:「今回は銀座Railsに参加できずでした😓」「報告記事上げます~」
後でmorimorihogeさんから伝え聞いた@a_matsudaさんのRailsパフォーマンス話の要点も興味深い内容でした😋。
追記
なお、前回の銀座Rails#12で評判だった@jnchitoさんのライブコーディング動画が有料公開されました🎉。
8/29の #ginzarails で使ったライブコーディング動画(?)を公開しました!ただし、今回はBOOTHでの有料販売にさせてもらってます。また、当日は倍速再生でしたが、こちらは等速です▶️
【動画】プログラマがコードを書きながら考えること 〜動画でわかるWebクローラー開発〜 https://t.co/RPmNL67DMj— Junichi Ito (伊藤淳一) (@jnchito) September 8, 2019
以下はその後のツイートです。
ブログ書きました。先週販売を開始したプログラミング動画の売上げを一部寄付させてもらいました。
BOOTH動画の売上金の一部を京アニと佐賀県と千葉県に寄付しました - give IT a try https://t.co/YQzdQLaHcH— Junichi Ito (伊藤淳一) (@jnchito) September 17, 2019
⚓その他Rails
- 元記事: 10 Ruby on Rails Blogs You Should Be Following
- 元記事: Node.js,Python,RubyなどのWebアプリを完全無料でホスティング可能な「Unubo」を使ってみた! - paiza開発日誌
つっつきボイス:「Unuboがはてブでバズってたので」「ニフティクラウドC4SAみたいに滅びる可能性も高いので、あくまで練習用という感じがするのと、あとどこの誰が運用しているのかがサイト見てもよくわからなかった🤔」
参考: NIFTYCloud-C4SA/support: ニフティクラウドC4SA ドキュメント・FAQ・質問等はこちらへ
ニフティクラウド C4SAは、2017年11月30日をもちまして、サービスを終了いたしました。 これまで長らくご愛顧賜り、誠にありがとうございました。
同リポジトリより
⚓Ruby
⚓るびま0060号リリース🎉
つっつきボイス:「るびまサイトがRSSフィードしていることについ昨日気づきましたので、Slackでフィードを受けるよう設定しました😅」「るびま、Rubyistは必読なので読んでない人はぜひ🎉」
⚓スライド: Ruby 3のキーワード引数
上のスライドは今年のRubyKaigiより少し前に以下のissueに貼られているのを見つけました。最終的にJeremy Evansさんの案がベースになったようです。
つっつきボイス:「上のスライドは方針決めのためのもので、結局どうなるのか・どうすればいいのかをissueでまだ追いきれていないのですが😅、以下あたり↓が比較的まとまってそうです」「breaking changesなので、次のRubyKaigiでも話題になる気がしますね」「もしかするとmameさんがそのうちブログにまとめてくれるかもしれないとひっそり期待してます🙏」
⚓RubyのUnboundMethod
この間のTokyo Rubyist Meetupで@ベストマサフミさんが発表後にこれをテーマに即興LTをやったのを見て知りました。
参考: Ruby|UnboundMethodで遊んでみた - Qiita
その他Ruby
# 同記事より
# Defining sub_scorer which is used at multiple places
# and based on some condition it is updating scores
def sub_scorer(scores)
...
scores << 50 if condition
...
end
# Defining final_scorer which may call sub_scorer
def final_scorer
begin
scores = [10, 20, 30].freeze
sub_scorer(scores)
rescue FrozenError => e
# We can now gracefully handle Frozen object violations
# based on the receiver
if e.receiver == scores
return "Can not modify scores"
else
return "Can not modify frozen objects"
end
end
end
final_scorer
#=> "Can not modify scores"
Link: ISUCON9の予選をRubyで通過しました - NaCl非公式ブログ: https://t.co/gONScnVgJ4
— Yukihiro Matz (@yukihiro_matz) September 11, 2019
⚓その他
⚓書籍とか
- 書籍: O'Reilly Japan - レガシーコードからの脱却 -- 9/19発売だそうです
つっつきボイス:「今度こそ技術書典行ってみたかったんですがまたしても都合がつかなくて😭」「技術書店、人が多いのが苦手過ぎて行けてないので自宅からOculus QuestとかでVR参加したいなあ」
⚓「ロックインの回避」にロックインされるな(Morning Cup Of Codingより)
ロックインを避けようとするあまり:
- 余分な工数がかかる
- コストもかかる
- 利便性が落ちる
- さらに複雑になる
- さらに別のロックインに陥る
つっつきボイス:「martinfowler.comの記事ですが書いたのはMartin Fowlerさんではありませんでした」「あるある: リスク管理で大事なのはリスクの洗い出しとコストを含めたトレードオフの認識であって、無限のリソースをかけてロックインを回避するというのは全くの悪手(国防方面や原発・プラント制御みたいなものだと例外はあるけど)」
前編は以上です。
おたより発掘
キーワード引数ころころ変わりすぎ〜
未だにキーワード引数の存在意義が分からない週刊Railsウォッチ(20190917-1/2前編)Sidekiq 6.0がリリース https://t.co/aJkXBKyYXs
— Jaga Apple (@jagaapple_tech) September 17, 2019
バックナンバー(2019年度第3四半期)
週刊Railsウォッチ(20190910-2/2後編)buildersconと「20年後のソフトウェアテスト」、はてなブックマークがScalaに移行、「詳解PostgreSQL」、Go 1.13ほか
- 20190909-1/2前編 Rails 6のキャッシュバージョニング、Rubyのキーワード引数周りが変わる、Faker 2がリリースほか
- 20190902 Ruby 2.6.4セキュリティ修正リリース、スライド「All About Ruby in 2019」、Shrine gem 3.0に入る新機能ほか
- 20190826 6-0-stableの更新を見てみる、『Morning Cup of Coding』ニュースレター、Rails TutorialがRails 6対応に動き出すほか
- 20190821-2/2後編 11のgemにバックドア、ruby-jp Slackがとてもアツい、Fullstaq Rubyでチューンアップ、HTTPサービス監視chaoほか
- 20190819-1/2前編 祝: Rails 6がついにリリース、RailsガイドもRails 6に対応、Arelはpublicだったかほか
- 20190806-2/2後編 RSpec CopのLeakyConstantDeclaration、serveoでゼロコンフィグ公開、RuboCopのPerformance/RegexpMatch改修ほか
- 20190805-1/2前編 Rails 6のActive Recordは速くなった、Windows WSL2+VSCodeでのRails開発、Martin Fowler記事ほか
- 20190730-2/2後編 Docker 19.03の新機能に注目、ngrokはスゴい、redis-namespaceほか
- 20190729-1/2前編 Rails 6のリリースは近そう?、Evil MartiansのRails+Docker記事、Railsパフォーマンス測定ほか
- 20190723-2/2後編 Rails 6 rc2がリリース、「MySQLパフォーマンスチューニングTips」が超便利、Aurora Serverlessほか
- 20190722-1/2前編 Rails 6エラー画面の改良点、Dateを四捨五入できるtime_calc、Rackミドルウェアのデザインパターンほか
- 20190717-2/2後編 NFSのよさとは、Linuxカーネル5.2リリース、Puppeteerでメモリリーク検出ほか
- 20190709-2/2後編 strong_password v0.0.7がハイジャックされていた、TerraformとCloudFormation、CSSの設計ミスリストほか
- 20190708-1/2前編 ActiveRecord::FixtureSetがめちゃ強くなってた、MacだとRubyが遅い理由、Puma 4登場ほか
- 20190701 RMagickのメモリ使用量が劇的に改善、インスタンス変数の定義順で速度が変わる?、GitLab CIランナーをローカルで回すほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSなど)です。