rails: Controllers and models don't reload in dev with Puma Workers enabled

Steps to reproduce

  1. Create a new Rails 5.0.0rc1 app
  2. Create a dummy route, controller, and controller action
  3. Uncomment the workers ENV.fetch("WEB_CONCURRENCY") { 2 } line from puma.rb
  4. rails server
  5. Visit your action
  6. Introduce an exception into the action
  7. Re-visit the action

Expected behavior

The new exception that was introduced should be raised.

Actual behavior

The page loads fine and the new code added to the action is ignored.

System configuration

Rails version: 5.0.0rc1

Ruby version: 2.3.1

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 33 (18 by maintainers)

Commits related to this issue

Most upvoted comments

Yes, commenting out this line makes the problem go away:

  # config.file_watcher = ActiveSupport::EventedFileUpdateChecker

I’m able to load $ rails server, add raise "foo" to a controller, load the page. Then remove the exception and reload the page, and the exception goes away.

Shooting in the dark here, maybe listen has a connection to something that cannot be shared between processes. Not really sure.

Still having this issue, Rails 5.1.4, puma 3.10. Contrary to what @schneems said above, running puma instead of rails s does not fix the issue. Any updates?

Ain’t running more than one worker something undesireable for a development flow? What’s your use case for running 2+ puma workers on development?

Debugging gets pretty difficult - There’s a chance that the logs might mislead you, as something happening on one worker won’t prevent another worker to process another request… I’ve seen it happen pretty regularly on a project I’m stuck with this same situation. Plus, using debugger/binding.pry is a bit painful, as the Puma master process detects that a worker timed out - 'cause your’e busy doing stuff on the command line - then kills the worker you were happily debugging, and replaces it with a new one. It also sends your current terminal to hell when that happens.

The only use case I can come up with is for benchmarking concurrency on the developer’s workstation… but for that I prefer to launch the app in “production” mode - not “development” - anyways…

Just experienced this today: Rails 6.0.3 ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux]

Commenting out: config.file_watcher = ActiveSupport::EventedFileUpdateChecker in config/environments/development.rb helped with this issue, thanks for that 🎉.

It may be useful to point out, this was only a problem with namespace routes for some reason for me. Changing view files would not render the changes unless I stopped and restarted the rails server. Spent an hour debugging before stumbling (googling) on this.

Just to say, with Rails (5.1.5) and Puma (3.11.2) on macOS, it is still necessary to comment out the config.file_watcher = ActiveSupport::EventedFileUpdateChecker config to have controllers reloaded. Switching to ActiveSupport::FileUpdateChecker instead of commenting the whole line fixes the problem too.

@Glutexo This that doesn’t resolve the issue for me unfortunately.

Just experienced this today: Rails 6.0.3 ruby 2.7.1

Commenting out: config.file_watcher = ActiveSupport::EventedFileUpdateChecker in config/environments/development.rb “solve” the issue for me.

Also using namespace routes as patrick 😄

This bug seems to exist in Puma v. 3.9.1

Is there some other version I should get, or some workaround? Nothing mentioned above works for me.

(This is my first experience w Puma - I discovered it a few hours ago and am trying to transition a client over to it.)

So https://github.com/rails/rails/blob/755f6bf3d3d568bc0af2c636be2f6df16c651eb1/activesupport/lib/active_support/evented_file_update_checker.rb#L54-L58 is getting called but not in a process that is running any code. When this happens it updates the @updated variable but that variable isn’t shared with the child processes which are handling the web requests.

In the code reloading executor gets called we could store all the PID numbers of all processes that are booted with Listen code and then compare that to the current process PID, if they don’t match spawn a new listen process. I’m not sure the best/cleanest way to do that. It would add a PID check to each request.