rastam’s blog

東京在住のマレーシア人 Rubyist

Ruby Weekly #371: 日本語サマリー

職場の Slack の #ruby 窓で Ruby Weekly メルマガが毎週配信されます。その中から面白そうなものをピックアップして、日本語で簡単なサマリーを書くようにしています。そのサマリーをここでまとまさせていただきます。くだけた日本語で失礼いたします。

http://rubyweekly.com/issues/371rubyweekly.com

Highlights

Configuring Puma, Unicorn and Passenger for Maximum Efficiency

Puma、Unicorn、Passenger を効率よく設定する方法。

  • サーバ毎に 3 子プロセス以上。上限は (合計 RAM / (あなたのウェブアプリのプロセスの 12 時間経過後の RAM * 1.2)) で計算。
  • MRI はサーバ毎に 5 スレッドで良い。JRuby は子プロセス数同様に計算。
  • とりあえず preloading オンにしようぜ。
  • サーバは RAM 1GB 以上。正確には 5 スレッドの 1 ワーカの 12 時間経過後の RAM * 3 で計算。

時間経過とともに膨らんだ Puma ワーカー。

Why Ruby App Servers Break on macOS High Sierra

先月発表された macOS High Sierra 上の Puma 不具合解説。

  • macOS が許可している fork 後処理が変わった。
  • 許可されてない処理を踏んだアプリサーバが Objective-C エラーを起こす。Objective-C に一切依存していないのに。
  • Apple 社が High Sierra の fork 挙動を変えたのは、Objective-C の fork 対応をやりやすくするため。
  • Puma などアプリサーバ開発者は、Ruby 言語レベルで対応すべきだと主張してる。
  • ワークアラウンドを実装したのは Passenger のみ。
  • Puma、Unicorn、iodine ユーザは環境変数指定で一応対応できる。

Fastest Way to Profile a Method in Ruby

Ruby メソッドの最も軽量なプロファイリング方法。

  • 時間計測は Time.now ではなく Process.clock_gettime(Process::CLOCK_MONOTONIC)
  • メソッドのパッチは prepend ではなく alias_method
  • スレッドセーフにする必要がある場合は、Thread.current["hoge"] でデータ保存。

Passenger 5.1.11 Released: A Key Security Release

Passenger 5.1.11 リリース。

  • システムフィアルが一覧表示できちゃう脆弱性対応
  • macOS High Sierra 対応
  • HTTP/2 対応
  • 遅延ポートバインディング用オプション追加
  • root 権限チェック・忠告追加

Visualizing Rails Logs With Jupyter Notebook

「重いよ!」と訴えるユーザに応じて、Jupyter NotebookRails ログ可視化手順。

  1. lograge logstash-event logstash-logger gem でログのフォーマットを JSON に。
  2. ユーザ ID をスレッドのローカル変数に持たせる。
  3. Jupyter Notebook の json_normalize() 関数で Pandas Dataframe にログをインポート。
  4. Dataframe.head で全体データをサニティーチェック。異常なし。
  5. Dataframe.describe で全体データを集計チェック。異常なし。
  6. 全体データのヒストグラム生成。異常なし。
  7. ユーザのデータに絞ったヒストグラム生成。異常なし。
  8. ユーザの 1 秒以上かかったコントローラ・アクションの棒グラフ生成。異常あり。

ROM 4.0.0 Released: The Ruby Object Mapper

ROM 4.0.0 リリース。

  • rom-repository gem のスキーマ自動マッピング(カラム情報を DB から読み込む機能)が ROM コアにて実装された。
  • rom-repository gem の auto_struct マッピング(データを Struct に設定する機能)が ROM コアにて実装された。
  • カスタム Struct が定義可能に。
  • changesetrom-changeset gem に抽出された。

News

Monitor, Debug and Log Your Ruby Apps with Stackdriver

GCP でも AWS でも使える stackdriver gem を紹介した Aja Hammerly 先生。

Tutorial

Rescue Specific Errors. Avoid Rescuing StandardError

rescue では例外をちゃんと指定しようぜ、という催促。

  • rescue Exception だと、SignalException::Interrupt まで rescue され、強制終了できなくなっちゃう。
  • rescue => e だと、予期せぬバグが隠蔽されちゃう。

Using JSON Web Tokens for Authentication in Distributed Systems

分散システム(マイクロサービスなど)の共通認証を JWT で実装する方法。Devisejwt gem を採用した例。

OOP and Rails System Tests

オブジェクト指向Rails システムテストを整理する方法。gem なしでページオブジェクトパターンを実装し、partial など共通 UI をモジュールに抽出している。

Migrating Data From MongoDB to Postgres with No Downtime

MongoDB が用途に合わなくなった Contractually 社がダウンタイムなしで PostgreSQL にデータを移行した 3 ステップ戦略。

  1. 第 1 デプロイ:稼働中のデータを MongoDB にも PostgreSQL にも WRITE。READ は MongoDB から。
    • Mongoid のコールバックで PostgreSQL に書き込むバックグラウンドジョブをキューに積む。
    • 12〜36 時間で移行完了の想定。
  2. 第 2 デプロイ:稼働中のデータの READ も WRITE も PostgreSQL から。
    • NewRelic でパフォーマンス・エラー発生率監視。
  3. 第 3 デプロイ:Mongoid、MongoDB 削除。
    • 予めバックアップ。

What Can You Do with The Array#zip Method?

Array#zip 活用案いろいろ。

  • 2 つの配列を比較する。
  • 2 つの配列の各インデックスの最大値を取得する。
  • キーの配列と値の配列を結合してハッシュを作る。
  • Enumerable#count とチェーンして同一要素を数える。
  • シーザー暗号を実装する。

The Command Pattern in Ruby

ホテルを例に挙げたコマンドパターン解説。

  1. 宿泊客がルームサービス、ランドリー、観光地パンフレットをコンシエルジュに注文。
  2. コンシエルジュが注文を厨房、クリーニング作業員、ベルボーイに依頼。

そのまま実装すると Concierge オブジェクトにキモい case 文ができてしまう。各注文をコマンドオブジェクトにすることで、Concierge がロジック分岐せずに実行できるようになる。おまけに

  • Concierge 以外のオブジェクトにも引数として渡せる。
  • 注文をキューに積むことができる。
  • 注文をログに残すことができる。
  • 注文を巻き戻すことができる。

Sanitize Attributes Through Your Form Object with Virtus

Virtus gem のフォームオブエクトでデータをサニタイズする例で、Virtus::Attribute#coerce でホワイトスペースを文字列から消してる。

A Practical Guide to Using ActionCable

プロジェクト管理ツールの UI をリアルタイムで更新するための ActionCable 実用ガイド。Build A SaaS App in Rails 5 本の抜粋。

Exploring Functional Programming with Ruby

関数型プログラミングをずっと警戒してた Rubyist をやっと説得できたリンク 3 つ。

  1. Rubyオブジェクト指向関数型プログラミングを融合した、dry-rb コアチームの Piotr Solnica 先生のトーク
  2. dry-rb コアチームの Tim Riley 先生のブログシリーズ
  3. Hanami 作成者 Luca Guidi 先生のトーク

Code

InvoicePrinter 1.0: PDF Invoice Generation from Ruby

請求書 PDF 生成用 InvoicePrinter gem。 見辛い Prawn コードをカプセル化したのが売り。

Karafka: A Ruby Framework for Working with Apache Kafka

Kafka + Ruby アプリ用 MVC フレームワーク

Hanami 1.1.0.rc1 Released

Hanami v1.1.0.rc1 リリース

  • アソシエーションの alias 定義可能に belongs_to :user, as: :author
  • カスタムスキーマのデータ型を任意 Entity で設定可能に
  • hanami generate model コマンドの新規オプション --relation (テーブル名)
  • RSpecメタデータ追加