Tech Racho エンジニアの「?」を「!」に。
  • 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がリリース

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#sendRactor.receiveRactor.yieldRactor#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するにもロックが必要、たしかに」「やはりデッドロックするのか」

参考: デッドロック - Wikipedia

  • ロックのアプローチに代えて、データベースのトランザクションの概念をメモリに適用する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の略なんですね」

ruby-concurrency/concurrent-ruby - GitHub

  • Ractor同士の変更が競合した場合は再実行される(その場合インスタンス変数やI/O処理は元に戻らない)
  • Ractor.atomicallyはネストできる

「『STMの実装』を見ると、STMは時刻をベースにしているらしい」「Ractor.atomicallyが自由にネストできるというのがスゴい」「ネストしても大丈夫だろうかと一瞬思っちゃいました」「読み出しのみの操作でもロールバックするとやり直しになる、だから再実行しても安全になるのか」

  • STMはRuby 3.0ではリジェクトされたが、gemとして公開している↓

ko1/ractor-tvar - GitHub
ko1/ractor - GitHub

「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より)

lib-ruby-parser/lib-ruby-parser - GitHub


つっつきボイス:「まだ新しくて★は少ないですが、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でパースしたいときはこれでしょうね😆」

ruby/spec - GitHub

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より)

mcmire/super_diff - GitHub


つっつきボイス:「なるほど、通常だとテストがfailするとデータ構造のdiffがベタに表示されるけど、それをこんなふうに賢く表示するのか↓」「これはスーパー」「賢い〜」「複雑なデータ構造のdiffを見たいときによさそう👍」


同リポジトリより

DB

M1とPostgreSQL

つっつきボイス:「これはデータベース関連のベンチマークかな?」「縦軸は秒あたりのトランザクション数、横軸はクライアント数か」「これが出典のようです↓」

参考: 【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の仕様が公開されないとできないでしょうね」

参考: リーナス・トーバルズ - Wikipedia

その他

スクラムガイド更新版が日本語に


つっつきボイス:「スクラムガイド改訂版が日本語化されたそうです」「改定されてだいぶ短くなったらしいとはてブかどこかで見かけました↓」「スクラムの仕様は定義が厳しくて、資格を取らないとスクラムマスターを名乗れないですね」「BPSでも厳密にスクラムのやり方に則って開発をしているチームはなかったと思います」

参考: スクラムガイドの変更点(2017→2020)から見えるスクラムチームが陥りやすい3つの罠
参考: スクラムマスターの役に立つ認定資格・研修一覧|オッドイー

番外

外からわかる


つっつきボイス:「最近こういう外からわかる系の技術をよく見かけるなと思って」「3つ目の記事には、脳が今聞いている音楽や言葉を判定するというのがありました」「2つ目の記事にあるロボット掃除機で音を取る手法なども昔から研究されている技術ですね: 音は物体を揺さぶるので、音の周波数より十分高いサンプリングレートで揺さぶりを観測できれば原理的に可能」「はい、窓ガラスを外からレーザー光線で測定して部屋の中を盗聴するなんてのも20年ぐらい昔にニュースになったのを覚えてます」「それだけ音の周波数は光に比べて低いということですね」

参考: レーザーマイクロフォン - Wikipedia


後編は以上です。

バックナンバー(2020年度第4四半期)

週刊Railsウォッチ(20201201前編)switch_pointがActive Record 6.0でサポート終了、Rails DBトランザクションの落とし穴ほか

今週の主なニュースソース

ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp SlackやRedditなど)です。

Ruby Weekly

RubyFlow

160928_1638_XvIP4h


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。