- Ruby / Rails関連
週刊Railsウォッチ(20210615後編)RubyのRBSを理解する、シンボルがGCされないとき、Terraform 1.0リリースほか
こんにちは、hachi8833です。
🔗Ruby
🔗 Rubyの新しい型注釈システムRBSを理解する(Ruby Weeklyより)
つっつきボイス:「記事はRBSとは何かから始めて詳しく解説している感じですね」「JetBrains IDEもRBSに対応するようになりましたし、RBSの記事が増えるのはいいですね👍」
🔗 Codewarsで見かけたRBS
「ところで、今日のWebチーム内ミーティングの発表で取り上げられていたCodewars↓という最近のプログラミング練習サイトはUIも含めてなかなかよくできていて、そこのRubyの練習問題の中にRBSが書かれているものもあったんですよ」「お〜、RBSがそんなところに!」
「全部の問題というわけではなさそうでしたが、たまたま開いたRubyの問題文でRBSを説明に使っていました: RBSのこういう使い方を見たのは初めて」「面白そう〜」「Rubyのバージョンも 2.5.0と3.0.0を選べるんですね」「CodewarsはブラウザエディタのキーバインドをVimやEmacsにもできるところが個人的にポイント高い: そのままだとブラウザのショートカットとぶつかることもあるようですけど」「あるあるですね」
CodewarsのGitHubリポジトリにissue trackerも見つけました↓。
以下はつっつき後に見つけたツイートです。
Codewars Ruby 1 kyu の「Ruby の中に書ける Haskellish な文法を作る」というやつが Ruby の狂気的文法拡張力を最大限利用しててめっちゃいいですね https://t.co/kYbzaE6Rhm
— うーねこ (@unecochan) February 21, 2020
🔗 YJITの現在(Ruby Weeklyより)
つっつきボイス:「Shopifyが作っているもうひとつのRuby JITであるYJITは以前もウォッチで取り上げましたね(ウォッチ20210420)」「Yはyet anotherのY」「MJITの後で始まったプロジェクトだったと思いますが盛んに活動してますね」
「この記事の途中でEuruko 2021でのMatzが引用されていて↓、しばらくはRuby言語仕様への追加を控えるそうです」「なるほど、言語仕様を変更するとJITなどのソース自体を解析して処理するような実装にも影響が出てしまうので、そういう方針も大事なのかもしれませんね」
Matz has stated in his recent talk at Euruko 2021 that Ruby would remain conservative with language additions in the near future. We believe that this is a wise decision as rapid language changes can make it difficult for JIT implementations to get off the ground and stay up to date. It makes some sense, in our opinion, for Ruby to focus on internal changes that will make the language more robust and deliver competitive performance in the future.
同記事より
以下のEuroko 2021の動画↓(1:16:50で頭出し)で、Ruby 3.1の言語仕様変更は極力控えめにするとMatzが話しています。
🔗 死なないシンボル(Hacklinesより)
- 元記事: The immortal symbols
つっつきボイス:「メタプロでシンボルがGCされないことがあるという記事のようです」「mortalが『死すべき定めの』で、タイトルで使われているのがその反対のimmortal(不死身の)ですね」
# 同記事より
$ ruby inmortal.rb
{:T_SYMBOL=>28, :T_STRING=>10136}
{:T_SYMBOL=>38, :T_STRING=>10228}
{:T_SYMBOL=>38, :T_STRING=>7793} # GC後もシンボルの個数が減っていない
respond_to_missing
とmethod_missing
の中でメソッド新規作成を回避すると、不死身のシンボルが発生しなくなり、インスタンスで必要なものだけになります。
同記事より大意
🔗 その他Ruby
Ruby 2.5だけじゃなくて、2.6、2.7、3.0の差異を紹介している記事もあります〜🍒 チェリー本のサンプルコードを最近のRubyで動かすときは要チェック!
Ruby 3.0で発生する「プロを目指す人のためのRuby入門」との差異について - Qiita https://t.co/ULgx112xaa https://t.co/BNxySTGC3j
— Junichi Ito (伊藤淳一) (@jnchito) June 8, 2021
🔗DB
🔗 pg_query: PostgreSQLのSQL文字列からPostgreSQL準拠のパーサーツリーを取り出すgem(Ruby Weeklyより)
つっつきボイス:「pganalyze.comというサービスが出しているgemだそうです」「こういうパーサーツリー↓を出力できるということは、PostgreSQL内部の挙動を調べるのに使うのかな」
# 同リポジトリより
#=> #<PgQuery::ParserResult:0x00007fb69a958820
@query="SELECT 1",
@tree=<PgQuery::ParseResult:
version: 130002,
stmts: [
<PgQuery::RawStmt:
stmt: <PgQuery::Node:
select_stmt: <PgQuery::SelectStmt:
distinct_clause: [],
target_list: [
<PgQuery::Node:
res_target: <PgQuery::ResTarget:
name: "",
indirection: [],
val: <PgQuery::Node:
a_const: <PgQuery::A_Const:
val: <PgQuery::Node:
integer: <PgQuery::Integer: ival: 1>
>,
location: 7
>
>,
location: 7
>
>
],
from_clause: [],
group_clause: [],
window_clause: [],
values_lists: [],
sort_clause: [],
limit_option: :LIMIT_OPTION_DEFAULT,
locking_clause: [],
op: :SETOP_NONE,
all: false
>
>,
stmt_location: 0,
stmt_len: 0
>
]
>,
@warnings=[]>
「includeフォルダにあるヘッダーファイルは同じくpganalyzeのlibpg_queryのものみたい: これでPostgreSQLのライブラリを参照してクエリパーサーの内部を解析して正規化したツリーを返すネイティブ拡張のように見えますね」「サンプルコード↓にもコネクションの記述がないので、PostgreSQLサーバーがなくても動きそう」
# 同リポジトリより
parsed_query = PgQuery.parse("SELECT * FROM users")
# Modify the parse tree in some way
parsed_query.tree.stmts[0].stmt.select_stmt.from_clause[0].range_var.relname = 'other_users'
# Turn it into SQL again
parsed_query.deparse
#=> "SELECT * FROM other_users"
「以下の1番目と2番目のクエリのfingerprint
が一致しているのは、SQL文字列では差異があっても、パーサーレベルでは値部分が抽象化されたり、コメントなどSQL実行と無関係なものが取り除かれたりして一致するということでしょうね↓」
# 同リポジトリより
PgQuery.parse("SELECT 1").fingerprint
=> "50fde20626009aba"
PgQuery.parse("SELECT 2; --- comment").fingerprint
=> "50fde20626009aba"
# Faster fingerprint method that is implemented inside the native C library
PgQuery.fingerprint("SELECT ?")
=> "50fde20626009aba"
「このツールを使えばお手製パーサーを作らずにPostgreSQL内部のクエリパーサーの挙動を確実に追えるのがよさそう👍」「こんなツールを作る人たちがいるのか〜」「Ruby以外にもGoやNodeやPython版もありますね」
🔗クラウド/コンテナ/インフラ/Serverless
🔗 Fastlyの障害(Publickeyより)
- 元記事: Fastlyが大規模障害の経緯を公開、原因はソフトウェアのバグ。障害を1分以内に検知し、49分でおおむね復旧させたと報告 - Publickey
- 元記事: Summary of June 8 outage | Fastly
つっつきボイス:「Fastlyの障害はニュースでも取り上げられていました」FastlyのようなCDNサービスはこれまであまり一般に知られていませんでしたけど、これをきっかけにCDNの認知度が高まるかも」
「今回のFastlyの障害でAmazonのECサイトの画像が配信されなくなっていたことで(購入とかは普通にできていたようです)、Amazon自身のECサイトがFastlyを使っていることがわかったのが個人的に発見でした」「あら、自社でCloudFront持っているのに使ってないのか〜」「でもAmazonは今回の障害でCloudFrontを使って復旧させてましたけどね」「最初からそうすればよさそうですけど」「もしかするとFastlyの方が安いなどの事情があって、CloudFrontをバックアップ用にしているのかもしれないと想像してみました」
参考: Amazon CloudFront(グローバルなコンテンツ配信ネットワーク)| AWS
🔗 VarnishのVCL
「FastlyはVarnishをホスティングしてエッジ配信しているサービスですが、自分はほとんど使ったことがなかったので、この機会にちょっと調べてみると、ひとつ驚いたのがVarnishのVCLという設定ファイルをFastlyのユーザーが書けるという点」「え、なかなか大胆ですね」
参考: Varnish (ソフトウェア) - Wikipedia
参考: Fastly VCL 入門 - Qiita
「VCLはnginxのコンフィグと似たような感じで宣言型言語っぽく書けるんですが、if
などの条件式や正規表現なども書けるのでコンフィグできる範囲が結構大きい」「ユーザーが設定間違えたらまた何か起きたりして」「Fastlyの顧客側の設定変更がきっかけでバグが顕在化したそうですが、VCLの記述自由度が高いことによるかどうかは推測の域を出ません」
参考: CDNのFastly、世界的な障害の原因は「ソフトウェアのバグ」 - CNET Japan
「コンフィグに正規表現が使えるということは、もしかすると最近流行りのCatastrophic Backtrackingが起きたのかも」「VCLの正規表現はそれほど強力ではなかったと思ったんですが、今見るとPerl互換正規表現(PCRE)構文を使っていると書かれているので↓、バックトラックを使うタイプだとしたらその可能性もあるかもしれませんね」
参考: VCL 正規表現早見表 | Fastly ヘルプガイド
🔗 CDNを冗長化できるか
「今後こういう事故に備えるにはどうしたらいいんでしょうね」「WebサービスでCDNを使おうとする場合、CDNサービスを複数使って冗長化しようとするととても複雑になりますし、常にスタンバイさせておかないといけないのでコストもかさみますね」「それもそうか」「マルチCDNでディザスタリカバリ的なことをやるのはあまり現実的ではないかなと思います: FastlyのVCLと同じ設定を、他のCDNでも別の言語で書くのも大変ですし」
「どうしてもマルチCDN構成にしたいなら、エッジ側でのコンピューティングを諦めてコンテンツキャッシュだけ行うようにすれば、DNSを切り替えるだけでCDNを切り替えられるでしょうね」「なるほど」「たとえばAWSのRoute 53にはヘルスチェック機能があるので、理論上はマルチCDNをヘルスチェックして失敗したら切り離すことはできそうかなと思いました」
参考: Amazon Route 53(スケーラブルなドメインネームシステム (DNS))| AWS
🔗 Terraform 1.0がリリース(StatusCode Weeklyより)
つっつきボイス:「Terraformって今まで1.0じゃなかったんですか」「リリースノートによると0.15.5から1.0のバージョンアップで、特に大きな変更はなさそうなので、節目の意味で記念にリリースしたのかも」「とにかくおめでとう🎉」「以前のRuboCopもなかなか1.0が出ませんでしたけど、それでもみんな使ってるという意味ではTerraformもそうですね」
🔗 Terraformよもやま話
「ちなみにTerraformコマンドは実行する際のTerraformバージョンをtfstateファイルのバージョンと合わせる必要があります: HashCorpのTerraform Cloudを使うか、事情があってローカルで実行するならtfenvなどの任意バージョンを切り替えられるツールを使うと便利です」「なるほど」
参考: Infrastructure as code with Terraform and GitLab | GitLab
「Terraformでしくじると大変なので、特にtfstateファイルをS3などに保存する設定にしておくのが重要: Terraformを最後に実行した人のtfstateファイルが残っていないと後でつらいことになります」「お〜」「なお、使ったことはありませんが、GitLabにもTerraformのインテグレーションがあります↓」
参考: Terraformのtfstateをざっと理解する - Qiita
参考: Infrastructure as code with Terraform and GitLab | GitLab
後編は以上です。
バックナンバー(2021年度第2四半期)
週刊Railsウォッチ(20210608後編)RubyでAppleのLZFSE圧縮データ解凍、AWS Lambda Extensionsが正式リリース、unixgame.ioほか
- 20210607前編 ActiveRecord::Relationのone?とmany?が高速化、RubyKaigi Takeout 2021登壇者募集開始ほか
- 20210601後編 Python使いから見たRuby、MySQLのインデックス解説、GitHubが採用したOpenTelemetryほか
- 20210531前編 RailsConf 2021の動画が公開、GraphQLのN+1を自動回避、Ruby 3のJITとRailsほか
- 20210525後編 Rubyのオブジェクトアロケーション改善、RubyKaigi Takeout 2021開催日発表、AWS App Runnerほか
- 20210524前編 Active Supportの知られてなさそうな機能5つ、RSpecの歴史、書籍『Practicing Rails』ほか
- 20210518後編 RubyのGCを深掘りする、Psych gemのbreaking change、11月のRubyConf 2021ほか
- 20210517前編 Bootstrap 5リリース、productionでSQLiteがwarning表示、rails-ujsの舞台裏ほか
- 20210511後編 AWS Lambda関数ハンドラをDSLで書けるyake gem、VPC Peeringが同一AZ転送量無料化ほか
- 20210511後編 AWS Lambda関数ハンドラをDSLで書けるyake gem、VPC Peeringが同一AZ転送量無料化ほか
- 20210510前編 属性メソッドをキャッシュして最適化、Railsのガバナンスに関する声明、bundle install高速化ほか
- 20210427後編 RactorでUDPサーバーを作る、JSONシリアライザalba gem、AppleのAirTagほか
- 20210420後編 ShopifyのJITコンパイラYJIT、PicoRuby、DynamoDBの3つの制約ほか
- 20210419前編 RailsのN+1クエリを定番以外の方法で修正する、GitLabのセキュリティ修正リリースほか
- 20210413後編 RubyMineのRBSサポートとCode With Me、GitHub ActionとDockerレイヤキャッシュほか
- 20210412前編 Active Record属性暗号化機能がRails 7にマージ、RailsNew.ioでrails newオプションを生成ほか
- 20210407後編 エイプリルフールのRuby構文プロポーザル、AWSのVPC Reachability Analyzerほか
- 20210406前編 GitHubが修正したRailsセッションハンドリングの競合、erb/haml/slimの速度比較ほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp SlackやRedditなど)です。
週刊Railsウォッチについて
TechRachoではRubyやRailsなどの最新情報記事を平日に公開しています。TechRacho記事をいち早くお読みになりたい方はTwitterにて@techrachoのフォローをお願いします。また、タグやカテゴリごとにRSSフィードを購読することもできます(例:週刊Railsウォッチタグ)