こんにちは、hachi8833です。
🔗Ruby
🔗 提案: gemに署名するメカニズム(Ruby Weeklyより)
つっつきボイス:「Shopifyの記事です」「お、gemに署名を付けやすくするしくみについての提案のようですね」「なるほど」「gemへの署名を何らかの形で自動化しないとgem作者がつらくなるからでしょうね」「署名の手間を軽減する提案なんですね」「gemに邪悪なコードを入れられてしまう問題はときどき起きるので、gemへの署名はたしかに必要: この間のrubygems.orgのAPIキー発行の改良もその流れの一環かもしれませんね(ウォッチ20220209)」
「記事が長いので流し読みの範囲ですが、たとえばトークンを適切な時期に失効させる議論もしていそう」「その辺大事そうですね」「有効期限が長過ぎるトークンはそれ自体セキュリティ上よくないので」
🔗 二要素認証アプリよもやま
「ところで話は変わるんですが、この間iPhoneをやむを得ず初期化したときに、Google Authenticatorアプリに登録した二要素認証の設定が飛んでしまって、他の二要素認証は手動で復元したものの、Rubygems.orgの二要素認証の復元方法が見当たらなくて、ruby-jp Slackで教えていただいたサポートのメアドに今問い合わせているところです😢」「ありゃ〜それは大変そう」「リカバリーキーは持っているのでログインはできるんですが、二要素認証を解除する画面でワンタイムパスワードを求められてしまいました」
「そうならないためにはクラウド上に設定を保存できる二要素認証アプリを使うのが確実でしょうね」「はい、Rubygems.orgのヘルプページにもそういうアプリの方がいいよと注意書きがありました😅」「Google Authenticatorのように特定デバイスのみで使える二要素認証の方がたしかにセキュアですけど、デバイスを紛失したり使えなくなったときが痛い」「たしかに」
「ちなみに1Passwordには二要素認証機能もありますよ」「え、自分も1Passwordの有料ユーザーですけどそんな機能が入っているんですか?自分もそうしようかな...🤔」
参考: 家族、ビジネス、チームのためのパスワード管理ツール | 1Password
追いかけボイス:
ごもっともでした🙏。Rubygems.orgで紹介されていたAuthyやAuthenticator Plusなどのクラウドにデータを置く二要素認証アプリを検討してみることにします。
参考: 「Twilio Authy」をApp Storeで
参考: Authenticator Plus
その後Rubygems.orgのサポートから連絡をいただき、二要素認証を復元できました🙇。リカバリーキーをワンタイムパスワードの欄に入力するのがポイントでした。
参考: Setting up multi-factor authentication - RubyGems Guides
🔗 RubyコードのWasmをブラウザ実行するのに1日かからなかった(Ruby Weeklyより)
つっつきボイス:「RubyをWasmとブラウザで動かす記事だそうです」「他のスクリプト言語の詳しい事情はわかりませんが、少なくともRubyは多くの基本機能が本体に入っているので、こういうときに外部gemを追加しなくてもかなりのことができるのがいいですよね」
🔗 依存関係の混乱による脆弱性と戦う(Ruby Weeklyより)
つっつきボイス:「これもShopifyの記事で、600以上のアプリで依存関係の混乱による脆弱性を解決したそうです」「Shopify頑張ってる」「Bundlerでの依存関係の混乱ってこういう感じのヤツか↓」「こういうのって自分で見ていてもわからなくなりがち」「このgemとこのgemが特定バージョンの組み合わせでインストールできなくなったりすることってたまにありますよね」
# 同記事より: 新しいバージョン
GEM
remote: https://example.com
specs:
private_gem (1.8.0)
dependency_1
dependency_2 (>= 2.7, < 4)
GEM
remote: https://rubygems.org/
specs:
public_gem (6.1.4)
dependency_1
# 同記事より: 古いバージョン
GEM
remote: https://example.com
remote: https://rubygems.org/
specs:
private_gem (1.8.0)
dependency_1
dependency_2 (>= 2.7, < 4)
public_gem (6.1.4)
dependency_1
「普段のBundlerは何も考えずに楽に使えますけど、ひとたび問題が起きるとトラブルシューティングで手間取りがち」「そうそう」「古いRailsプロジェクトで起きがちなのも大変...」「ちょうど次の記事もBundler関連です」
🔗 Bundler v2.3でBundler自身のバージョンがロックされるようになった(Ruby Weeklyより)
つっつきボイス:「Bundler v2.3からBundler自身のバージョンをロックするようになったそうです」「今までは該当バージョンのBundlerがなかったときは最新バージョンにフォールバックしていたのが、v2.3からはBUNDLED WITH
のバージョンどおりのBundlerを使うようになったのね」
「Bundlerはある時期からGemfile.lockの末尾にBUNDLED WITH
を追加するようになりましたけど↓、メンバーの誰かが不用意にローカルでbundle install
したものをコミットしたりするとCIが止まったりすることがありましたね」「あ〜そうそう」「あれはマジでつらい😢」
# Gemfile.lockの末尾の例
RUBY VERSION
ruby 3.1.0p0
BUNDLED WITH
2.3.5
「この問題が起きるとBundlerが期待どおりに動かなくなるので、BUNDLED WITH
を取り入れるなら互換性を失わない形にして欲しかったとよく思ったものです」「今の自分の環境でBundlerがうまく動かないのってもしかするとこの辺の問題なのかも...」
「BundlerがRuby本体に取り入れられてgem install bundler
しなくてよくなってからはあまり起きなくなりましたけど、それまではメンバーごとにBundlerのバージョンが合っていない可能性がちょくちょくあった」「そんな時代もありましたね」「それでも個別にBundlerを手動でインストールすると起きたりしますけどね: レビューで気づけばいいけど見逃すとCIが死ぬ」
🔗 その他Ruby
つっつきボイス:「最近流行りのWordleをRubyで解いてみたそうです」「英語圏でどえらく流行してますよね」「まだ遊んでないけど」「自分も」
参考: Wordle - The New York Times
「Wordleはノリ的には女神転生のコードブレイカーっぽいかも」「リモートワーク流行りのおかげで盛り上がってるのかもしれませんね」
参考: コードブレイカー - 真・女神転生IMAGINE攻略Wiki
参考: code breakerの意味・使い方・読み方 | Weblio英和辞書 -- code breakerは推理小説のジャンルでもあるようです
「ついでにゲームの話をすると、最近のイベントで見たこのGeoGuessrというゲームを集団で解く動画がものすごかった↓」
参考: GeoGuessr | AGDQ2022 - Twitch
「ジオゲッサーという名前からして、Googleマップのストリートビューを見て場所を当てるとか?」「そうそうそんな感じ: 推測した場所を地図上でクリックして正解の場所と距離が近いほど高得点になる」「お〜なるほど」「最初のうちはエッフェル塔みたいなわかりやすい名所ですけど、だんだんどこの山だか砂漠だかわからないような場所に放り出される」「うまいところに目を付けたゲームですね」「元の動画は英語ですけど日本語で解説されてます」
🔗DB
🔗 mini_sql: 最小限のSQLエグゼキュータ(Ruby Weeklyより)
つっつきボイス:「Discourseのgemだそうです」「PostgreSQLとSQLiteのインターフェイスを持つ、よくある感じのシンプルなクエリエグゼキュータのようですね: プレースホルダ機能や、クエリ結果をeach
で回すみたいなことができるらしい↓」「デコレータを足してRubyっぽく書けるんですね」
# 同リポジトリより
pg_conn = PG.connect(db_name: 'my_db')
conn = MiniSql::Connection.get(pg_conn)
puts conn.exec('update table set column = 1 where id in (1,2)')
# returns 2 if 2 rows changed
conn.query("select 1 id, 'bob' name").each do |user|
puts user.name # bob
puts user.id # 1
end
# extend result objects with additional method
module ProductDecorator
def amount_price
price * quantity
end
end
conn.query_decorator(ProductDecorator, "select 20 price, 3 quantity").each do |user|
puts user.amount_price # 60
end
p conn.query_single('select 1 union select 2')
# [1,2]
p conn.query_hash('select 1 as a, 2 as b union select 3, 4')
# [{"a" => 1, "b"=> 1},{"a" => 3, "b" => 4}
p conn.query_array("select 1 as a, '2' as b union select 3, 'e'")
# [[1, '2'], [3, 'e']]
p conn.query_array("select 1 as a, '2' as b union select 3, 'e'").to_h
# {1 => '2', 3 => 'e'}
「mini_sqlは昔にさかのぼったかのようなデータベースコネクションライブラリという感じかな」「そういえばRuby Weeklyではsafeと紹介されていました」「どれどれ、mini_sqlは毎回できるだけ結果セットをクリアするからmemory bloatしにくいというのがsafeということみたい」「あ、そういうことですか」「ちなみに、一般的にアプリケーション側のメモリ効率としては、結果セットを一気に全部取り出すよりSQLのカーソルで取り出す方が有利」
参考: Ruby's external malloc problem
「mini_sqlはおそらくeach
で結果セットを取り出すたびに結果セットをクリアするんじゃないかな: lib/の下のコードを見てみるとquery_each
で毎回result.clear
を呼んでいる↓」「なるほど、こまめに片付けてmemory bloatを避けているんですね」「GCに任せてもいいんですが、GCされるまではメモリに乗り続けるので、明示的にクリアする方が片付くのは早いでしょうね」
# https://github.com/discourse/mini_sql/blob/main/lib/mini_sql/postgres/connection.rb#L106
def query_each(sql, *params)
raise StandardError, "Please supply a block when calling query_each" if !block_given?
if params && params.length > 0
sql = param_encoder.encode(sql, *params)
end
raw_connection.send_query(sql)
raw_connection.set_single_row_mode
loop do
result = raw_connection.get_result
break if !result
result.check
if result.ntuples == 0
# skip, this happens at the end when we get totals
else
materializer ||= deserializer_cache.materializer(result)
result.type_map = type_map
i = 0
# technically we should only get 1 row here
# but protect against future batching changes
while i < result.ntuples
yield materializer.materialize(result, i)
i += 1
end
end
result.clear
end
end
「mini_sqlはどんなときに使えるんでしょうか?」「少なくともActive Recordの代わりに使うものではないと思いますが、プレースホルダのような最小限の機能は備わっているので十分コードは書けますね: 十数年前のPHPでもmysqli_fetch_assoc
とかでこんな感じでコードを書いてましたよ」「あ〜、PHPerだったので今のですべて理解できました、あのノリですね」
参考: PHP: mysqli_result::fetch_assoc - Manual
「毎回メモリをクリアするということは効率は高い代わりに当然速度が犠牲になるので、mini_sqlが合うかどうかは用途次第ということになるんでしょうね」「そうそう、ものすごく巨大なデータセットから取り出したいときとか、メモリが潤沢でない環境で使いたいとか」
「Railsはメモリが潤沢な環境が前提なので、極端なことをしない限りそうそうスラッシングしませんけど、たとえばAWS Lambdaのようにメモリが限られたFaaS的環境で巨大なデータセットからちょっぴり取り出したいときだったら、mini_sqlのようにこまめにクリアするアプローチが合うかも👍」「なるほど」「型変換とかはできないので、そういう機能が豊富なActive Recordとはあり方からして違うでしょうね」
🔗クラウド/コンテナ/インフラ/Serverless
🔗 Google CloudでサーバーレスSparkが一般公開(Serverless Statusより)
つっつきボイス:「お、Sparkだ」「GoogleのBigQueryからも使えるようになるんですって(現時点では非公開プレビュー)」「Sparkって何でしたっけ?」「Apache Projectのひとつであるオープンソースの分散フレームワークですね」「言われてみればApacheのサイトでロゴを見たことあったかも」「そのSparkをサーバーレスで使えるようになったのか」
参考: Apache Spark™ - Unified Engine for large-scale data analytics
参考: Apache Sparkとは何か――使い方や基礎知識を徹底解説:Amazon EMRで構築するApache Spark超入門(1)(1/3 ページ) - @IT
「SparkはHadoopのお仲間的な感じ」「HadoopはたしかHDFSが元になっていましたね」
参考: 分散処理技術「Hadoop」とは:NTTデータのHadoopソリューション
参考: HDFS(Hadoop Distributed File System) とは | 技術関連用語集 | BBTowerレポート | 株式会社ブロードバンドタワー
「AWS S3はHDFSでもあるそうなので、EMRでHDFSを使いたいときはS3に置けばいいというのが魅力的だなと思いました: S3にJSONとかを置いたらHadoopが読み込んでくれるようにできる」「HadoopのストレージをS3で代替できる?」「はいそんな感じです: AWSでHadoopを使いたければECS上にHDFSのクラスタを構築しないといけないのかなと思ってたら、それS3でできるよということでした」「へ〜」
参考: Amazon EMR(Hadoopなどのビッグデータフレームワークを簡単に実行)| AWS
「言われてみればS3には当初からHDFSがあったかも」「そうそう、ありましたね」「S3の中身はHDFSとかなり違いそうな気もしますけど、オーバーレイネットワーク上でマルチノードをまたがる単一のファイルシステムを構築するという意味では、S3とHDFSがやりたいことはそんなに遠くないかも」「中身は違ってそうですけどそんな感じですね: Sparkはそれをメモリ上に構築するヤツです」「ははぁなるほど」
「サーバーレスのSparkってペタバイト級のメモリでも使えるのかな?」「Googleならやれそうな気もしますけどね: お金次第でしょうけど」
🔗 GCPとAWS
「何度か話していますが、GCPのあり方はAWSといろいろ違うので使う側の学び方も違ってきますよね: AWSは責任共有モデルで、基本的にコンピュテーションパワーやインフラやAPIの部分だけを提供して、その上で何をするかは自由だけど責任もユーザー側にある、FaaS的なサービスもランタイムまでは用意するけど運用やメモリ管理などはユーザーに委ねるというスタンス」「そうそう」
参考: 責任共有モデル | AWS
「GCPの印象は、Googleのサポートがアプリケーションレイヤまで及んでいる感じで、むしろアプリケーションライブラリ的な側面を感じる」「わかります」「アプリケーションエンジニアとしては、GCPにどっぷり浸かる方がいろいろ便利に使えるのかもしれませんね」
「その分GCPはアプリケーションライブラリのドキュメントをみっちり読まないといけないんですが」「それそれ!ドキュメントをもうちょっと親切に書いて欲しいです😢」
「逆にAWSはLinuxの知識があれば基本的にやれますよね(AWS自体の知識を別にすれば)」「ほんとそう😆」「AWSはLinuxの知識と経験がそのまま通用するし新サービスの概要もつかみやすいけど、GCPの場合はまずサービスのパラダイムから確認しないといけない感じ」「そこなんですよ」「結果セットが1000件以上のときはこっちのメソッドを使うこと、みたいなのをGCPで見かけたりしますね」
🔗言語/ツール/OS/CPU
🔗 IntelがRISC-Vに大規模投資
つっつきボイス:「今さらだけどRISC-Vってリスクファイブって読むんですね」「RISC-Vはオープンソースの命令セットアーキテクチャ(ISA)」「Intelがそこにドカンと投資したのか」(しばしItaniumなどの話題)
ちょっとまって、RISC-V International の Premier Members に、面白い企業の名前が出てきたぞ。Intel っていうんですが……。https://t.co/9ktgwyfToD
— Tsukasa #01 (fully vaccinated) (@a4lg) February 7, 2022
最近聞いた採用例では Samsung のそれが象徴的だと思うのよね。スマートフォンの華とも言えるプロセッサは実績とソフトウェア資産を持つ Arm アーキテクチャではあるが、その背後の目立たない (かつ既存のソフトウェア資産が重要でない) ところにおいて、RISC-V が重要な機能を支えている。
— Tsukasa #01 (fully vaccinated) (@a4lg) February 8, 2022
「ツイートにもありますけど、量販店で売られているような民生用機器の組み込み系で最近RISC-Vが続々使われ始めているのが自分的にとてもアツい」「たしかにワイヤレスイヤフォンとかもろ民生用ですね」「そうなるとARMの組み込み市場と完全に競合するので、ARMや日本のルネサスあたりが今後どうなるかも含めて気になっています」「黒船感ありますね」
参考: ARMアーキテクチャ - Wikipedia
参考: ルネサスエレクトロニクス - Wikipedia
後編は以上です。
バックナンバー(2022年度第1四半期)
週刊Railsウォッチ: Rails 7.0.2の改修内容、receipts gemでレシートを作成ほか(20220214前編)
- 20220209後編 Rubygems.orgのAPIキーに権限スコープが追加、RailsのDBパフォーマンス改善ほか
- 20220208前編 Rails 6.1を7.0にアップグレードしてみた、PostgreSQLでジョブキューほか
- 20220201後編 Rubygems Adoptionフォームが開設、JetBrains Gateway、NGINX Unitほか
- 20220131前編 Sidekiqが10歳に、BuildKiteのテストを高速化、フィーチャーフラグほか
- 20220126後編 Rubyコンパイラの歴史動画、RubyのWebAssembly対応進む、ぼっち演算子の注意点ほか
- 20220124前編 Webpackerが公式に引退宣言、『Everyday Rails』日本語版がRails 7に対応ほか
- 20220118後編 Ruby 2.5〜3.1ベンチマーク、Opal 1.4、JRubyが20歳に、2022年のCSSほか
- 20220117前編 rails-ujs->Turboアップグレードガイド、RubyとWeb Componentsほか
- 20220112 Rails 7をRuby 3.1で動かす、クックパッドのRuby 3.1解説記事、Rails 6->7更新ほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp SlackやRedditなど)です。
週刊Railsウォッチについて
TechRachoではRubyやRailsなどの最新情報記事を平日に公開しています。TechRacho記事をいち早くお読みになりたい方はTwitterにて@techrachoのフォローをお願いします。また、タグやカテゴリごとにRSSフィードを購読することもできます(例:週刊Railsウォッチタグ)