Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

週刊Railsウォッチ(20210615後編)RubyのRBSを理解する、シンボルがGCされないとき、Terraform 1.0リリースほか

こんにちは、hachi8833です。

週刊Railsウォッチについて

  • 各記事冒頭には🔗でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
  • 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄
  • お気づきの点がありましたら@hachi8833までメンションをいただければ確認・対応いたします🙇

TechRachoではRubyやRailsなどの最新情報記事を平日に公開しています。TechRacho記事をいち早くお読みになりたい方はTwitterにて@techrachoのフォローをお願いします。また、タグやカテゴリごとにRSSフィードを購読することもできます(例:週刊Railsウォッチタグ)

🔗Ruby

🔗 Rubyの新しい型注釈システムRBSを理解する(Ruby Weeklyより)


つっつきボイス:「記事はRBSとは何かから始めて詳しく解説している感じですね」「JetBrains IDEもRBSに対応するようになりましたし、RBSの記事が増えるのはいいですね👍」

ruby/rbs - GitHub

🔗 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/codewars.com - GitHub

以下はつっつき後に見つけたツイートです。

🔗 YJITの現在(Ruby Weeklyより)

Shopify/yjit - GitHub


つっつきボイス:「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より)


つっつきボイス:「メタプロでシンボルが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_missingmethod_missingの中でメソッド新規作成を回避すると、不死身のシンボルが発生しなくなり、インスタンスで必要なものだけになります。
同記事より大意

🔗 その他Ruby

🔗DB

🔗 pg_query: PostgreSQLのSQL文字列からPostgreSQL準拠のパーサーツリーを取り出すgem(Ruby Weeklyより)

pganalyze/pg_query - GitHub


つっつきボイス:「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サーバーがなくても動きそう」

pganalyze/libpg_query - GitHub

# 同リポジトリより
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の障害はニュースでも取り上げられていました」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 ヘルプガイド

はじめての正規表現とベストプラクティス10: 危険な「Catastrophic Backtracking」前編

🔗 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などの任意バージョンを切り替えられるツールを使うと便利です」「なるほど」

tfutils/tfenv - GitHub

参考: 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ほか

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

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

Ruby Weekly

Hacklines

Hacklines

StatusCode Weekly

statuscode_weekly_banner

Publickey

publickey_banner_captured


CONTACT

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