💎
Puma の Cluster mode で TypeError が発生する
Rails アプリで Puma の Cluster mode を使おうとしたら下記のようなログが表示され、リクエストが返ってこなかった。
# 起動時
/Users/foo/.anyenv/envs/rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/stringio-3.1.0/lib/stringio.bundle: warning: already initialized constant StringIO::VERSION
# リクエスト時
2024-03-29 11:42:22 +0900 Listen loop: #<TypeError: wrong argument type strio (expected strio)>
調べたところ下記の条件で発生するらしいことがわかった。
- Puma を Cluster mode で起動
- Puma で
prune_bundler
を有効に - bootsnap を使っていて load_path_cache を有効に (
require "bootsnap/setup"
使っていれば有効) - Ruby 3.2 (3.0, 3.1 では発生しないことを確認)
- Gemfile.lock に psych がある
上記の条件を満たした上で require "yaml"
を実行すると前掲の起動時のログが表示される。デフォルトだと bootsnap 内で require "yaml"
が呼ばれるが、ここ以外で呼んでも同じ。
いまのところ根本的な解決方法がわかっていない (どこの issue に投げたらいいのかもわからない...) ので上記の条件のいずれかを回避する。
再現
mkdir puma_bootsnap_issue
cd puma_bootsnap_issue
rbenv local 3.2.2
# Gemfile
source "https://rubygems.org"
gem "bootsnap", "~> 1.18"
gem "sinatra", "~> 4.0"
gem "psych", "~> 5.1"
gem "puma", "~> 6.4"
# my_app.rb
require "bootsnap/setup"
require "yaml"
require "sinatra/base"
class MyApp < Sinatra::Base
get "/" do
"Hello"
end
end
# config.ru
require "./my_app"
run MyApp
bundle
BOOTSNAP_CACHE_DIR=. bundle exec puma --prune-bundler -w 2
Discussion