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 ワーカー。
先月発表された macOS High Sierra 上の Puma 不具合解説。
- macOS が許可している fork 後処理が変わった。
- 許可されてない処理を踏んだアプリサーバが Objective-C エラーを起こす。Objective-C に一切依存していないのに。
- Apple 社が High Sierra の fork 挙動を変えたのは、Objective-C の fork 対応をやりやすくするため。
- Puma などアプリサーバ開発者は、Ruby 言語レベルで対応すべきだと主張してる。
- ワークアラウンドを実装したのは Passenger のみ。
- Puma、Unicorn、iodine ユーザは環境変数指定で一応対応できる。
Ruby メソッドの最も軽量なプロファイリング方法。
- 時間計測は
Time.now
ではなくProcess.clock_gettime(Process::CLOCK_MONOTONIC)
。 - メソッドのパッチは
prepend
ではなくalias_method
。 - スレッドセーフにする必要がある場合は、
Thread.current["hoge"]
でデータ保存。
Passenger 5.1.11 リリース。
「重いよ!」と訴えるユーザに応じて、Jupyter Notebook で Rails ログ可視化手順。
- lograge logstash-event logstash-logger gem でログのフォーマットを JSON に。
- ユーザ ID をスレッドのローカル変数に持たせる。
- Jupyter Notebook の
json_normalize()
関数で Pandas Dataframe にログをインポート。 Dataframe.head
で全体データをサニティーチェック。異常なし。Dataframe.describe
で全体データを集計チェック。異常なし。- 全体データのヒストグラム生成。異常なし。
- ユーザのデータに絞ったヒストグラム生成。異常なし。
- ユーザの 1 秒以上かかったコントローラ・アクションの棒グラフ生成。異常あり。
ROM 4.0.0 リリース。
- rom-repository gem のスキーマ自動マッピング(カラム情報を DB から読み込む機能)が ROM コアにて実装された。
- rom-repository gem の
auto_struct
マッピング(データを Struct に設定する機能)が ROM コアにて実装された。 - カスタム Struct が定義可能に。
changeset
が rom-changeset gem に抽出された。
News
GCP でも AWS でも使える stackdriver gem を紹介した Aja Hammerly 先生。
- Stackdriver Debugger デバッグツール
- Stackdriver Error Reporting 例外モニタリングツール
- Stackdriver Trace パフォーマンスモニタリングツール
- Stackdriver Logging ログ管理ツール
Tutorial
rescue
では例外をちゃんと指定しようぜ、という催促。
rescue Exception
だと、SignalException::Interrupt
までrescue
され、強制終了できなくなっちゃう。rescue => e
だと、予期せぬバグが隠蔽されちゃう。
Using JSON Web Tokens for Authentication in Distributed Systems
分散システム(マイクロサービスなど)の共通認証を JWT で実装する方法。Devise と jwt gem を採用した例。
オブジェクト指向で Rails システムテストを整理する方法。gem なしでページオブジェクトパターンを実装し、partial など共通 UI をモジュールに抽出している。
MongoDB が用途に合わなくなった Contractually 社がダウンタイムなしで PostgreSQL にデータを移行した 3 ステップ戦略。
- 第 1 デプロイ:稼働中のデータを MongoDB にも PostgreSQL にも WRITE。READ は MongoDB から。
- Mongoid のコールバックで PostgreSQL に書き込むバックグラウンドジョブをキューに積む。
- 12〜36 時間で移行完了の想定。
- 第 2 デプロイ:稼働中のデータの READ も WRITE も PostgreSQL から。
- NewRelic でパフォーマンス・エラー発生率監視。
- 第 3 デプロイ:Mongoid、MongoDB 削除。
- 予めバックアップ。
Array#zip
活用案いろいろ。
- 2 つの配列を比較する。
- 2 つの配列の各インデックスの最大値を取得する。
- キーの配列と値の配列を結合してハッシュを作る。
Enumerable#count
とチェーンして同一要素を数える。- シーザー暗号を実装する。
ホテルを例に挙げたコマンドパターン解説。
- 宿泊客がルームサービス、ランドリー、観光地パンフレットをコンシエルジュに注文。
- コンシエルジュが注文を厨房、クリーニング作業員、ベルボーイに依頼。
そのまま実装すると Concierge
オブジェクトにキモい case
文ができてしまう。各注文をコマンドオブジェクトにすることで、Concierge
がロジック分岐せずに実行できるようになる。おまけに
Concierge
以外のオブジェクトにも引数として渡せる。- 注文をキューに積むことができる。
- 注文をログに残すことができる。
- 注文を巻き戻すことができる。
Virtus gem のフォームオブエクトでデータをサニタイズする例で、Virtus::Attribute#coerce
でホワイトスペースを文字列から消してる。
プロジェクト管理ツールの UI をリアルタイムで更新するための ActionCable 実用ガイド。Build A SaaS App in Rails 5 本の抜粋。
関数型プログラミングをずっと警戒してた Rubyist をやっと説得できたリンク 3 つ。
- Ruby のオブジェクト指向と関数型プログラミングを融合した、dry-rb コアチームの Piotr Solnica 先生のトーク
- dry-rb コアチームの Tim Riley 先生のブログシリーズ
- Hanami 作成者 Luca Guidi 先生のトーク
Code
請求書 PDF 生成用 InvoicePrinter gem。 見辛い Prawn コードをカプセル化したのが売り。
Hanami v1.1.0.rc1 リリース