puma: Phased restart crash when upgrading Rack Gem despite using 'prune_bundler'
Summary
I upgraded rack in my Gemfile and Puma/Bundler unexpectedly crashed on restart. As we use prune_bundler in our cluster and don’t preload, we expected that the Puma cluster master would be isolated from Gem changes, but able to respawn new workers which use the new Gems.
It only seems to crash if Gems directly used by Puma are upgraded. The version of Bundler doesn’t seem to matter (but not exhaustively tested.)
Have I understood the expected behaviour correctly? Any workarounds or suggestions welcomed.
How to replicate
The Production issue can be simply replicated in Development without needing to do a full deploy:
- My
Gemfile.lockspecifiesrack (1.5.2)andpuma (2.11.2) - Load gems:
bundle install - Config file as per the deployment guide
worker 2
threads 1
prune_bundler <-- The important bit
rackup DefaultRackup
port 3000
environment 'development'
- Let’s start Puma:
bundle exec puma -C ./config/puma.rb
* Pruning Bundler environment <-- Good
[9372] Puma starting in cluster mode...
[9372] * Version 2.11.2 (ruby 2.1.2-p95), codename: Intrepid Squirrel
[9372] * Min threads: 1, max threads: 4
[9372] * Environment: development
[9372] * Process workers: 2
[9372] * Phased restart available
[9372] * Listening on tcp://0.0.0.0:3000
[9372] Use Ctrl-C to stop
[9374] + Gemfile in context: /Users/<me>/Documents/<org>/<project>/Gemfile
[9375] + Gemfile in context: /Users/<me>/Documents/<org>/<project>/Gemfile
[9372] - Worker 0 (pid: 9374) booted, phase: 0
[9372] - Worker 1 (pid: 9375) booted, phase: 0
- Update the
Gemfile.lockto userack (1.5.3) bundle install- Ask for a phased restart:
kill -USR1 <pid of puma cluster master> - Crash:
/Users/<me>/.rvm/gems/ruby-2.1.2@<project>/gems/bundler-<version>/lib/bundler/runtime.rb:34: in `block in setup':
You have already activated rack 1.5.2, but your Gemfile requires rack 1.5.3.
Prepending `bundle exec` to your command may solve this. (Gem::LoadError)
About this issue
- Original URL
- State: closed
- Created 9 years ago
- Comments: 23 (20 by maintainers)
Hmm it’s harder than I thought. I was trying to get it to do a
bundle execinsideprune_bundlerbefore re-execing yet again without Bundler like it currently does. I don’t understand why it’s so complicated though. If you allow the Bundler environment in Puma itself, why can’t the restart simply be something like this?I quickly hacked this in and it seems to work here but maybe I’m missing the bigger picture.