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

週刊Railsウォッチ(20210511後編)AWS Lambda関数ハンドラをDSLで書けるyake gem、VPC Peeringが同一AZ転送量無料化ほか

こんにちは、hachi8833です。

週刊Railsウォッチについて

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

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

🔗Ruby

🔗 yake: AWS Lambda関数ハンドラをrake風に書ける(Ruby Weeklyより)

amancevice/yake - GitHub


つっつきボイス:「いぇーく?」「なるほど、handler DSLに続けてコードを書くとLambda Functionのコードに展開してくれる感じですね↓」「おぉー」「API Gatewayを統合する形でも書けるらしい」

# 同リポジトリより
# ./lambda_function.rb
require "yake"

handler :lambda_handler do |event|
  # Your code here
end

# Handler signature: `lambda_function.lambda_handler`
# 同リポジトリより
# ./lambda_function.rb
require "yake/api"

header "content-type" => "application/json"

get "/fizz" do
  respond 200, { ok: true }.to_json
end

handler :lambda_handler do |event|
  route event
rescue => err
  respond 500, { message: err.message }.to_json
end

# Handler signature: `lambda_function.lambda_handler`

参考: AWS Lambda を Amazon API Gateway に使用する - AWS Lambda

「こんなふうにSinatra風にルーティングを書くこともできる↓: yakeを使うとデプロイも含めてLambdaやAPI Gatewayを簡単に使えるようになるんでしょうね」

# 同リポジトリより
delete "/…" do |event|
  # Handle 'DELETE /…' route key events
end

get "/…" do |event|
  # Handle 'GET /…' route key events
end

head "/…" do |event|
  # Handle 'HEAD /…' route key events
end

options "/…" do |event|
  # Handle 'OPTIONS /…' route key events
end

patch "/…" do |event|
  # Handle 'PATCH /…' route key events
end

post "/…" do |event|
  # Handle 'POST /…' route key events
end

put "/…" do |event|
  # Handle 'PUT /…' route key events
end

「デプロイ方法はどこだろう?」「API Gatewayの定義もRubyで書いているから、デプロイ機能はあるはずですね(しばらく探す)READMEの下の方に、version.rbのバージョンを更新してからbundle exec rake releaseすると書かれてた」「あ、ここですか」「シンプルに使えるのはよさそう👍」

🔗 AWS LambdaでRuby 2.5サポートが間もなく終了

「Lambdaといえば、AWS LambdaでのRuby 2.5のサポート終了がアナウンスされましたね↓」「おぉ、ついに」「AWSからのお知らせメールで知りましたが、おそらくRuby 2.5レイヤを使っているユーザーにしかこのメール通知は来ていないと思います」

参考: ランタイムサポートポリシー - AWS Lambda

「サポート終了のフェーズ1が2021年7月30日から開始、フェーズ2が2021年8月30日から開始なのか」「もうすぐじゃないですか」「まだちょっと時間はあるかな」「なおRubyコミュニティでのCRuby 2.5のサポートは今年4月で既に終了しています↓」

参考: Ruby 2.5.9 Released

「AWS公式のLambdaランタイムのRubyは2.7なのかー」「そう、Lambda公式のRubyは最新安定版の3.0じゃないんですよ: なるべく長く使いたいので最新安定版で始めたいけど、Ruby 2.7だとその分期間が短くなるのが残念」


「ちなみにAWS Lambdaは昨年Rubyのマイナーバージョンを2.5.7から2.5.8に予告なしでアップグレードしたことがあって、めちゃくちゃ困りました」「えぇ!いきなりLambda関数動かなくなるのはつらい...」「gemをbundleしているコードだったんですが、Ruby本体のbundled gemであるjson gemのバージョンが上がったことでGemfile.lockの記述との差違が出てしまい、突然『何もしてないのに動かなくなった』という事態に陥りました」「おぉ...」「そのときにAWSのサポートに詳しくフィードバックしたおかげか、今回はちゃんと通知されました👍」「フィードバックは大事ですね」

🔗 ビットフィールドをRubyで扱う(Ruby Weeklyより)


つっつきボイス:「ビットフィールドといえば、C言語にあるけどあまり使ったことのない機能」「C書いたことないです...」「ビットフィールドはビットマスクの演算に使ったりしますね」

参考: ビット演算 - Wikipedia

「そうそう、こういう0oで始まるRubyの8進数リテラル、あまり見かけないけどありますね↓」

# 同記事より
irb> 0o644.to_s(2).rjust(12, "0").each_char.map { |b| b.to_i == 1 }
=> [false, false, false, true, true, false, true, false, false, true, false, false]

参考: リテラル (Ruby 3.0.0 リファレンスマニュアル)

「Rustだとこういう感じでビットフィールドを定義できるのね↓」

// 同記事より
#[macro_use]
extern crate bitflags;

bitflags! {
    struct Flags: u32 {
        const A = 0b00000001;
        const B = 0b00000010;
        const C = 0b00000100;
        const ABC = Self::A.bits | Self::B.bits | Self::C.bits;
    }
}

fn main() {
    let e1 = Flags::A | Flags::C;
    let e2 = Flags::B | Flags::C;
    assert_eq!((e1 | e2), Flags::ABC);   // union
    assert_eq!((e1 & e2), Flags::C);     // intersection
    assert_eq!((e1 - e2), Flags::A);     // set difference
    assert_eq!(!e2, Flags::A);           // set complement
}

「C言語だとまさにこう書く↓」

/* 同記事より */
#define S_IFMT   0170000
#define S_IFLNK  0120000
#define S_IFREG  0100000
#define S_IFDIR  0040000
#define S_IFCHR  0020000
#define S_IFIFO  0010000
#define S_ISUID  0004000
#define S_ISGID  0002000
#define S_ISVTX  0001000

#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)

「へ〜、Sequel::Modelを使うとenumっぽく書けるのか↓: ビットフィールドとenumは本来別物なのが気になるけど、enumっぽく書きたい人にはいいかも」

# 同記事より
class MyModel < Sequel::Model
  plugin :bit_fields, :status_bits, [ :started, :finished, :reviewed ]
end
model = MyModel.create

model.started?        # => false
model.started = true
model.started?        # => true
model.status_bits     # => 1

model.finished?       # => false
model.finished = true
model.finished?       # => true
model.status_bits     # => 3

# let's find all the finished instances
MyModel.finished(true).all

# let's find all unfinished instances
MyModel.finished(false).all

# let's find all the started and the finished instances
MyModel.started.finished.all

jeremyevans/sequel - GitHub

「そしてActive Recordでもbitfieldsというgemを使うとビットフィールドが使えるそうですよ↓」「こんなgemがあったとは」「1個のビットフィールドに最大64ビットまで定義できるらしい」「64ビットを使い切る場面はあまり想像できないかも🤔」

# 同記事より
class User < ActiveRecord::Base
  include Bitfields
  bitfield :my_bits, 1 => :seller, 2 => :insane, 4 => :sensible
end

grosser/bitfields - GitHub

「ビットフィールドは、シリアル通信やネイティブのネットワークプログラミングでパケット処理を書くような低レイヤの処理で必要になることがあります」「組み込み系の処理にもよくありますね」「頻度は年に数回ぐらいですが、使うときは使います」

参考: ビットフィールド - Wikipedia

🔗 リモートのzipファイルのファイルリストだけを取り出す(Ruby Weeklyより)

つっつきボイス:「そうそう、zipファイルは冒頭の部分をうまく取り出せば、全体をダウンロードしなくてもファイルリストを取れますね」「それをRubyでやってみた記事だそうです」「記事でzipのファイル構造も引用されてる↓: ファイルエントリはこういうふうにzipファイルの冒頭に集まってます」「お〜」

ZIP-64 Internal Layout
commons.wikimedia.orgより

「この種のテクニックは結構応用が効きます: S3に置かれている超巨大なzipファイルの中身を知りたいときとか」「やりたいときありますね」「mpegなどの動画・音声ファイルもメタ情報はたいていファイルの冒頭に置かれているので、zipと同じ考え方で処理できますね」

🔗 その他Ruby

つっつきボイス:「この記事を書いたBurdette Lamarさんは、最近英語版のRubyドキュメントを熱心に更新しているそうで、その更新履歴です」「ドキュメントが新しくなるのはありがたい!」「偉大な仕事👍」

🔗クラウド/コンテナ/インフラ/Serverless

🔗 AWS VPC Peeringの価格変更


つっつきボイス:「BPSの社内Slackに貼っていただいた記事です」「そうそう、VPC Peeringの転送にかかる料金が、同じAZ(Availability Zone)ID内では無料になるというお知らせ」「おー!」

参考: VPC ピア機能とは - Amazon Virtual Private Cloud

「ただし、AZの名前ではなくAZの"ID"を使う点に注意が必要です」「IDですか?」「ap-northeast-1aのようなAZは名前で、apne1-az3のように表記するのがIDです: AZ名がアカウントに依存する論理名だとすると、AZ IDはアカウントと無関係に物理データセンターにマッピングされます」「あ、なるほど」「AZ IDが同じならVPC Peeringのデータ転送が無料になるということですね(VPC Peeringそのものの利用料はかかりますが)」「AWSアカウント間で巨大なデータ転送を行いたいときとかにありがたい🙏」「ちょうど最近VPC PeeringとTransit Gatewayを使い始めたところです」

参考: リソースの AZIDs - AWS Resource Access Manager

🔗 Transit Gateway

「ちなみにVPC Peeringは文字どおり他のAWSアカウントと一対一で接続しますが、Transit Gatewayは、あるAWSアカウントのVPCにTransit Gatewayを作ると他の複数のAWSアカウントから接続できる、ルーター的な接続サービスです」「そんなことができるんですね!」「VPC Peeringは3拠点ぐらいまでなら何とかやれますが、拠点が増えると接続がメッシュ状に増えてしまうので、接続拠点が4つ以上ぐらいになったらTransit Gatewayの方が便利」「ふむふむ」

参考: AWS Transit Gateway(VPC およびアカウント接続を簡単にスケール)| AWS

「Transit GatewayはAWSアカウントのひとつをVPCホストにして他のAWSアカウントのVPC同士をルーターのように接続するので、ルーティングの設定も必要ですし、接続するVPC同士のIPアドレスが衝突してはいけないんですよ」「なるほど」「IPアドレスが衝突するとVPCを作り直さないといけなくなって、配下にあるEC2インスタンスなどもすべて作り直しになるので大変です😢」

🔗JavaScript

🔗 Romeプロジェクトが法人化(Publickeyより)


つっつきボイス:「BabelやLintのようなJSツールをRomeに集約するということみたいですね」「ツール事業の法人化は、責任や問い合わせや寄付先が一元化されるという意味ではありがたい」「法人を軌道に乗せられるかどうかが勝負でしょうね」


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

🔗 その他JS

つっつきボイス:「JSのArray.prototypeで提案されているイミュータブルなメソッド名が過去形の動詞になっているのが面白いと思って拾ってみました」「なるほど、popped()とかreversed()とかたしかに過去形」「Arrayを返すイミュータブルなメソッドが欲しいのはわかる」「後はこのメソッド名が受け入れられるかどうかでしょうね」


後編は以上です。

バックナンバー(2021年度第1四半期)

週刊Railsウォッチ(20210427後編)RactorでUDPサーバーを作る、JSONシリアライザalba gem、AppleのAirTagほか

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

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

Ruby Weekly

Publickey

publickey_banner_captured


CONTACT

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