- Ruby / Rails関連
週刊Railsウォッチ(20201202後編)Rails 6.1 RC2リリース、Ruby STMの詳細な解説記事、RSpecのdiffを見やすくするsuper_diff gemほか
こんにちは、hachi8833です。Rails 6.1 RC2が今朝リリースされたことをつい先ほど知りました。
- 各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
- 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄
- お気づきの点がありましたら@hachi8833までメンションをいただければ確認・対応いたします🙇
⚓ 臨時ニュース: Rails 6.1 RC2がリリース
Rails 6.1 RC2 has been released! We are approaching the final release. Please give it a try.https://t.co/NfoOHZPNkJ
— Ruby on Rails (@rails) December 1, 2020
6.1の主な新機能や改善点も上の記事でリストアップされています。
- マルチプルDBの強化(Horizontal Shardingなど多数)
- 関連付けのstrict loading(#37400、#38541)
- Delegated Typing(#39341)
- 関連付けをバックグラウンドジョブで非同期destory可能に(#40157)
ActiveModel::Error
(#32313)- Active Storageの強化(#34935など)
- deprecation warning発生時に
raise
するオプション(#37940) - 各種パフォーマンス向上およびバグ修正
- Zeitwerkより前のクラシックオートローダーが非推奨に
ウォッチ20200907でご紹介した@willnetさんのスライドを再録いたします。
⚓Ruby
⚓ @_ko1さんのSTM解説記事
つっつきボイス:「Software Transaction Memory(STM)を@_ko1さんが詳しく解説してくれてる!」「この間取り上げたSTMの英語記事のときはRactorとの絡みがよくわからなかったけど、@_ko1さんの記事はRactorにも関連して書かれていてありがたい🙏」(一同でしばらく読む)
「Ractorは基本的にスレッド間で共有するものがあってはいけないという考え方で、たとえばクラス変数もRactorでは使えないんですけど、それでも共有したいものがあるときのためにSTMを導入してはどうかという話を何かのイベントで聞いた覚えがあります」「記事でも、Ractorの外では基本的にオブジェクトを共有できないとありますね」
注: 本項の以下のイタリック箇条書きはつっつきで注目した部分を元記事から抜粋・要約したものであり、必ずしも元記事の流れに沿っていません。詳しくはぜひ元記事をご覧ください。
- Ractorではデータ共有のためにオブジェクトをコピーしてメッセージとして送受信する
Ractor#send
やRactor.receive
、Ractor.yield
とRactor#take
というメソッドが使える
「マルチスレッドプログラムやネットワークプログラミングではよくこのような形でデータを共有しますね」
そこで、Ractor では、メモリを共有するのではなく、オブジェクトをメッセージとしてコピーして送ったり受け取ったりすることで、データを共有します。
同記事より
- Ractorのオブジェクトの受け渡しは原則として参照ではなくコピーされる
- ただしコピーなしで受け渡しする場合もあり、それを共有可能オブジェクトと呼ぶ
「この辺の、どれを共有可能オブジェクトにできるか、何が共有できないかを追いかける話なども何かのイベントでしてませんでしたっけ?」「うう、思い出せない😢」「そのときにSTMの話もしてたように覚えてます」
- たとえばちょっとしたカウンタをRactor間で簡単に共有する方法が現在のRactorにない
- 単純なカウンタを集約して管理するRactorを作るといったことは可能
「カウンタのためにわざわざRactorを作りたくない気持ち、わかります」
- ロックによるメモリ共有を検討した
- しかし値をincrementするだけでもロックが必要になる
- ロックしないとアクセスできないインターフェイスを試したところ、デッドロックした↓
# 同記事より: デッドロックするコード
c1 = Counter.new(0)
c2 = Counter.new(0)
r1 = Ractor.new do
c2.lock do
c1.lock do
c1.value += 2
c2.value = c1.value * 2
end
end
end
c1.lock do
c2.lock do
c1.value += 1
c2.value = c1.value * 2
end
end
#...?
「値をincrementするにもロックが必要、たしかに」「やはりデッドロックするのか」
- ロックのアプローチに代えて、データベースのトランザクションの概念をメモリに適用するSTMを採用すればそうした問題を解決できるのではないかと考えた
「STMは、とりあえず読み書きして、アクセスが重複したらロールバックするというところがシンプルですね↓」
STM は、DB のトランザクション(楽観的ロック)と同じように、とりあえずなんか読み書きして、あとで、「あ、別の Ractor とアクセスが被った!」となったらロールバックしてしまいます。簡単ですね。
同記事より
- STMはreadしかしないのであれば並列化して速くなりそう
- 他にもメリットがある
- その代わりロールバックが多発すると遅くなる可能性がある
「STMのいろいろな流派の話も興味深い↓」「メモリ操作を全部transactionの対象にするアプローチは聞いたことある」「まさにコンピューターサイエンスの記事ですね」
- Rubyはすべてをロールバックすることはできないので、一部のメモリだけをSTMの対象にすることにする
- Ractorでは、
Ractor.atomically
でトランザクションを設定すると、Ractor::TVar.new
に置いた値だけがトランザクションの中でロールバック対象になる Ractor::TVar
は、Concurrent Rubyのインターフェイスを踏襲した
「これらのメソッドが既にconcurrent-rubyのThreadにあったとは知らなかった↓」「TVar
はtransaction variableの略なんですね」
- Ractor同士の変更が競合した場合は再実行される(その場合インスタンス変数やI/O処理は元に戻らない)
Ractor.atomically
はネストできる
「『STMの実装』を見ると、STMは時刻をベースにしているらしい」「Ractor.atomically
が自由にネストできるというのがスゴい」「ネストしても大丈夫だろうかと一瞬思っちゃいました」「読み出しのみの操作でもロールバックするとやり直しになる、だから再実行しても安全になるのか」
- STMはRuby 3.0ではリジェクトされたが、gemとして公開している↓
「Ractorを使い倒すのであればしばらくはgemでやることになりそう」「gemになった分少し性能は落ちるらしいけど、これはしょうがないですね」
「とても丁寧な解説記事で、しかもめちゃめちゃ面白い!」「実装の話も盛り込まれていて参考になります」「これを日本語で読めるのはありがたい🙏」
⚓ RactorやSTMの使われ方を想像する
「この記事で扱われているような、トランザクションをソフトウェアで行ってものすごい数の並列処理を行うといった話題は、Go言語などで作るようなマイクロサービス方面でよく登場しますね」「ふむふむ」「今後Rubyでそうした処理を行うときには、RactorとSTMが大事な考えになってくる気がします」
「RactorやSTMは、RailsのActive Recordのビジネスロジックみたいなアプリケーションコードよりは、もっとプリミティブなAPIサーバーでよく使われそうな気がします」「記事にもあったような、銀行口座の残高移動のように一貫性が一瞬でも崩れてはいけない処理でも使いたいです」
「今後RubyでRactorとSTMが本格的に使えるようになれば、現在はGo言語などで作られているような並列度の高いAPIサービスをRubyで手軽に書けるようになるかもしれませんね」
⚓ lib-ruby-parser: Rustで書かれたRubyパーサー(RubyFlowより)
つっつきボイス:「まだ新しくて★は少ないですが、RustでRubyパーサーを作ったというのが気になりました」「MRIのparse.y↓をそのままベースとしているので、完全にMRIと同じ順序でトークンを返すとある」「かつRipperプラスjemalloc
よりも速いそうです」
参考: ruby/parse.y at master · ruby/ruby
参考: class Ripper (Ruby 2.7.0 リファレンスマニュアル)
「レアなエッジケースを与えたらさすがにコケるかな?」「READMEを見るとトップ300 gemでテストされていて、しかもruby/spec↓やruby/rubyでもRipper.lex
と同じ結果が出ているとある!」「それはスゴい」「RubyをRustでパースしたいときはこれでしょうね😆」
⚓ ShopifyのSorbet利用状況
以下で知りました。
参考: 週刊気になったITニュース(2020/11/22号) - masa寿司の日記
つっつきボイス:「ShopifyでSorbetがどのぐらい使われているかという記事で、masa寿司さんの方で見る方が読みやすそうでした」「ファイルの80%以上が型付けされてるとは」「Shopifyは静的型付け方面もすごく頑張ってるな〜」「Shopifyはサービスの規模も巨大でエンジニアの数も多くて、エンタープライズWebアプリケーションのひとつの大きな流れを形成しつつある感じがしますね」「今後Sorbetの利用を指定する案件が出てくるようになったら面白そう😋」
後でShopifyのイベント↓を見てみましたが、今のところイベントの資料は見当たらないようです。
イベント: Shipit! Presents: The State of Ruby Static Typing at Shopify(終了)
類似記事: Adopting Sorbet at Scale — Development
⚓ super_diff: RSpecでデータ構造のdiffを見やすく整形(Ruby Weeklyより)
つっつきボイス:「なるほど、通常だとテストがfailするとデータ構造のdiffがベタに表示されるけど、それをこんなふうに賢く表示するのか↓」「これはスーパー」「賢い〜」「複雑なデータ構造のdiffを見たいときによさそう👍」
⚓DB
⚓ M1とPostgreSQL
まぁでもこれを見ると「おちつけー!」って感じはしますね。 pic.twitter.com/M6aJnqtjR0
— mattn (@mattn_jp) November 21, 2020
つっつきボイス:「これはデータベース関連のベンチマークかな?」「縦軸は秒あたりのトランザクション数、横軸はクライアント数か」「これが出典のようです↓」
参考: 【x軸とy軸の覚え方】 「横がx軸で縦がy軸です」ととっさに言えますか?! | SMATU.net
「ツイートのグラフを見る限り、M1はクライアント数が増えたときのトランザクション数の伸びが頭打ちになっている感じ」「このグラフがリニアであるほど、並列化がうまくいってることになりますね」「Ryzen 9はやっぱりスゴいという話」「Ryzenつよい💪」
⚓クラウド/コンテナ/インフラ/Serverless
⚓ 米バージニア州北部のAWS us-east-1リージョンで障害(現在は回復)
つっつきボイス:「我が家のSwitchBotは今の時点でまだ回復してません😇」「主にIoT系デバイスが影響を受けてるようですね」「見た感じでは影響を受けているのはIoTデバイスだけみたい」
参考: SwitchBot(スイッチボット) | スマートホームにらくらくスイッチ| Alexa | Google Home
「お、ステータスを見ると珍しくページトップで障害をレポートしている↓」「Tokyoリージョンの障害もトップに出して欲しい」「今日のお昼はもっと障害件数多かったんですけど、今はほぼ回復してる感じですね」「なるほど、IoT SiteWise以外はグリーンに戻ってる」
「AWSでは新しいサービスをまずus-east-1リージョンで立ち上げることが多いんですけど、Amazon Kinesisなどのサービスがまだそのリージョンにしかなかったんでしょうね」「AWSの新しいサービスをいち早く使ってる人はだいたいこのリージョンに乗っかりますけど、TOKYOリージョンに来るまで待ってから使い始めている人たちはたぶん無事だったんじゃないかな」
「記事を見ると家電が動かない報告がいろいろ上がってますね」「エアコンが動かなくて寒いとか」「ご飯が炊けなくなったとか、灯りがつかなくなって寝坊しそうになったというのも見かけました」
「エアコンは物理リモコンで回避できそうですけどね」「私はリモコンを手放さずに全部持ってますけど、リモコン使いたくない人は片付けちゃうのかも」「リモコン使いたくないからIoTを導入することも多いでしょうね」「いずれにしろこの種のデバイスはフォールバックパスを用意しておかないとこういうときに大変」
⚓言語/ツール/OS/CPU
⚓ M1とリーナス・トーバルズ
つっつきボイス:「リーナスはプロプライエタリな製品を好まないことで有名ですね」「記事にはLinuxをM1向けに最適化するつもりはないとあります」「M1 Macの仕様が公開されないとできないでしょうね」
⚓その他
⚓ スクラムガイド更新版が日本語に
つっつきボイス:「スクラムガイド改訂版が日本語化されたそうです」「改定されてだいぶ短くなったらしいとはてブかどこかで見かけました↓」「スクラムの仕様は定義が厳しくて、資格を取らないとスクラムマスターを名乗れないですね」「BPSでも厳密にスクラムのやり方に則って開発をしているチームはなかったと思います」
参考: スクラムガイドの変更点(2017→2020)から見えるスクラムチームが陥りやすい3つの罠
参考: スクラムマスターの役に立つ認定資格・研修一覧|オッドイー
⚓番外
⚓ 外からわかる
- 元記事: 自分が見ている色を他人に知られてしまう技術が開発される - ナゾロジー
- 元記事: マイクのないロボット掃除機を利用した盗聴の危険がある - GIGAZINE
- 元記事: 脳の情報を書き換えうつ病・難病治療。イーロン・マスクも本腰「ニューロテクノロジー市場」への期待 | AMP[アンプ] - ビジネスインスピレーションメディア
つっつきボイス:「最近こういう外からわかる系の技術をよく見かけるなと思って」「3つ目の記事には、脳が今聞いている音楽や言葉を判定するというのがありました」「2つ目の記事にあるロボット掃除機で音を取る手法なども昔から研究されている技術ですね: 音は物体を揺さぶるので、音の周波数より十分高いサンプリングレートで揺さぶりを観測できれば原理的に可能」「はい、窓ガラスを外からレーザー光線で測定して部屋の中を盗聴するなんてのも20年ぐらい昔にニュースになったのを覚えてます」「それだけ音の周波数は光に比べて低いということですね」
後編は以上です。
バックナンバー(2020年度第4四半期)
週刊Railsウォッチ(20201201前編)switch_pointがActive Record 6.0でサポート終了、Rails DBトランザクションの落とし穴ほか
- 20201201前編 switch_pointがActive Record 6.0でサポート終了、Rails DBトランザクションの落とし穴ほか
- 20201117後編 Rubyのパターンマッチングが3.0で本採用に、AWS Lambdaサイズを縮小する、AppleのM1チップほか
- 20201116前編 6.1のActive Storageでimage_processing gemが必須に、Webアプリ設計の変遷とフロントエンド領域の再定義ほか
- 20201111後編 RubyConf 2020が11/17〜19オンライン開催、GitHub Container Registryベータ開始、スマートロックほか
- 20201110前編 Rails 6.1 RC1がリリース、Railsアプリに最適なEC2インスタンスタイプ、n_plus_one_control gemほか
- 20201028後編 RuboCop 1.0.0 stable版がリリース、Ruby DSLのGUIフレームワークGlimmer、Keycloakほか
- 20201026前編 Shopifyのerb-lint gem、Form Objectを使いやすくするyaaf gem、railsrcの機能追加ほか
- 20201021後編 webpack 5リリースでWebpacker対応開始、AWS Lambda Extensions発表、Pythonにマクロ構文追加提案ほか
- 20201020前編 Percona Toolkitは優秀、Active Admin非公式ガイド、Railsをリアクティブにするガイドほか
- 20201013後編 ruby-type-profilerがtypeprofにリネーム、AWS API Gatewayの実行ログは便利、M5Stackほか
- 20201012前編 Railsの隠し機能routing visualizer、action_args gem、N+1用goldiloader gemほか
- 20201006後編 Rubyの
defined?
キーワード、Ractorベースのジョブスケジューラ、Caddy Webサーバーほか - 20201005前編 Ruby 2.7.2がリリース、Shopifyのモジュラー化gem「packwerk」、stimulus_reflexほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp SlackやRedditなど)です。