Puma 8.0.1リリース:`prune_bundler`のBUNDLE_*環境変数消失バグを修正
Puma 8.0.1では、prune_bundler使用時にユーザー設定のBUNDLE_*環境変数がre-exec時に消去されてしまい、ワーカーが起動クラッシュするバグが修正されました。あわせてデバッグログのパフォーマンス改善も含まれています。
背景
v8.0.0リリース後、prune_bundlerを有効にした環境でワーカーが起動に失敗する問題が報告されました。原因は、re-exec(プロセスの再実行)の際にBUNDLE_WITHOUTなどのユーザーが設定したBUNDLE_*環境変数が消去されてしまうことにあります。prune_bundlerはBundlerの環境をクリーンアップする機能ですが、ユーザーが意図的に設定した変数まで除去してしまっていました(#3929)。
この問題はBUNDLE_WITHOUTのように特定のgemグループを除外する設定を行っている本番環境で特に影響が大きく、ワーカープロセスが再起動のたびにクラッシュするという深刻な症状を引き起こしていました。
技術的な変更
今回のリリースに含まれる変更は以下の3つの分類に整理されます。
バグ修正:
-
prune_bundlerのre-exec時におけるBUNDLE_*環境変数の保持 (#3929): ユーザーが設定したBUNDLE_*環境変数がre-exec後も正しく引き継がれるよう修正。
パフォーマンス改善:
- デバッグログのブロック化 (#3920): デバッグログの生成をブロック渡しに変更し、デバッグが無効な場合にログメッセージ文字列が生成されないよう最適化。
ドキュメント修正:
バージョン文字列は lib/puma/const.rb 内の PUMA_VERSION / VERSION 定数が "8.0.0" から "8.0.1" に更新されています。
設計判断
デバッグログのブロック化は、Rubyにおける一般的なログ最適化パターンの適用です。ログレベルチェックをブロックの遅延評価で行うことにより、デバッグ無効時に不要な文字列補間やオブジェクト生成が発生しません。Pumaはパフォーマンスクリティカルなコンポーネントであるため、本番環境でデバッグログが無効な際のオーバーヘッドを削減する意義は大きいといえます。
prune_bundlerのバグ修正については、Bundler環境のクリーンアップ対象を「Pumaが管理する変数」に限定し、ユーザーが明示的に設定した変数は保護する方針で修正されています。
まとめ
Puma 8.0.1は、prune_bundlerを利用する環境でのワーカークラッシュという実害のあるリグレッションを解消するパッチリリースです。v8.0.0からのアップグレードは、特にBUNDLE_*環境変数を設定している本番環境において優先度の高い対応となります。