Setting Number of Puma Workers on Heroku - ruby-on-rails

Why do I have 4 Puma workers if I've set WEB_CONCURRENCY=3 in my Heroku config?
In this question, I learned that New Relic calls Puma workers "app instances".
Here is my puma.rb configuration:
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['MAX_THREADS'] || 1)
threads threads_count, threads_count
preload_app!
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'
on_worker_boot do
# Valid on Rails 4.1+ using the `config/database.yml` method of setting `pool` size
ActiveRecord::Base.establish_connection
end
Heroku config:
WEB_CONCURRENCY: 3

Puma has one master process.
It does not deal with request. It monitors and manages(restart or something) workers.
If you set 3 concurrency, there are 4 process. 3 workers(managing request) and 1 master precess(managing workers)

Related

Clustered puma not accepting more than 1 request concurrently

I have setup my puma web server based on heroku manual: Deploying Rails Applications with the Puma Web Server
config/puma.rb:
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 2)
threads threads_count, threads_count
preload_app!
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'
on_worker_boot do
ActiveRecord::Base.establish_connection
end
Procfile contains:
web: bundle exec puma -C config/puma.rb
Now when I try to access action which has sleep 10 which delays the response and then try to access some other action, my understanding was that Puma would handle these 2 requests concurrently (since I have 2 workers). But instead it waits for the first request which sleeps to finish then it proceeds to the second one. Am i missing something?
My setup is:
Ruby 2.2.4
Rails 4.2.0
EDIT:
Ok, so I found out that on Heroku, it works, so question is, why it doesn't work in development mode?
rails s does not use the Procfile, you may want to look at using a tool like foreman: https://github.com/ddollar/foreman
update: this was the solution:
config.allow_concurrency = true in the rails development config.

Run puma workers in Production, but not in Development

I'm running the following puma config
threads_count = Integer(ENV["DB_POOL"] || ENV["MAX_THREADS"] || 15)
threads threads_count, threads_count
workers 3
preload_app!
rackup DefaultRackup
port ENV["PORT"] || 3000
environment ENV["RACK_ENV"] || "development"
on_worker_boot do
ActiveSupport.on_load(:active_record) do
ActiveRecord::Base.establish_connection
end
end
before_fork do
ActiveRecord::Base.connection_pool.disconnect!
end
It's great for production, but I don't want to spin up 3 workers or use webrick in development. I tried wrapping the worker specific code in an environment check, but that breaks the puma DSL. Any ideas for running puma in non-clustered mode in development?
Rails is not defined in puma config file, so Rails.env can't be used here, but RACK_ENV is ok.
workers(ENV["RACK_ENV"] == "production" ? 3 : 0)
I figure out a working solution before seeing scorix's answer which I accepted, but I ended up with a slightly different solution. This allows you to set the worker count, so I can run 1 in staging and 3 in production for example.
threads_count = Integer(ENV["DB_POOL"] || ENV["MAX_THREADS"] || 15)
threads threads_count, threads_count
rackup DefaultRackup
port ENV["PORT"] || 3000
environment ENV["RACK_ENV"] || "development"
if ENV["RACK_ENV"] == "production"
workers ENV.fetch("WEB_CONCURRENCY") { 3 }
preload_app!
ActiveSupport.on_load(:active_record) do
ActiveRecord::Base.establish_connection
end
before_fork do
ActiveRecord::Base.connection_pool.disconnect!
end
end
Check out the Configuration part on the docs.
What I did was set up the production config on config/puma/production.rb, so on production you would run puma with puma -C config/puma/production.rb (or however you run it on prod) and on development, rails server won't use that configuration

Prepard statement already exist issue - puma incorrect config

I am using rails 4 with puma as my web server. I am using postgres on heroku
I am getting error saying that prepared statement already 'a3' exist
This is my conf for puma
# REF https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['MAX_THREADS'] || 5)
threads threads_count, threads_count
preload_app!
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'
on_worker_boot do
# Worker specific setup for Rails 4.1+
# See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot
ActiveRecord::Base.establish_connection
end
I think my config for ActiveRecord connection is causing a problem
This might help but I don't know how to do it for puma Postgres: prepared statement already exists
The rails issue linked from the question you referred to in your question has some suggestions.
The most popular seems to be removing the rack-timeout gem if it is included in your Gemfile. Does sound like a guaranteed solution but has helped someone people on that thread.

Running different rails webserver as per choice

now by default whenever I run rails s it starts rails with puma
I want to able to run webrick in my development environment as puma doesn't work well when debugging with byebug
# Gemfile
gem 'puma'
# config/puma.rb
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['MAX_THREADS'] || 5)
threads threads_count, threads_count
preload_app!
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'
on_worker_boot do
ActiveRecord::Base.establish_connection
end
You can achieve this by restricting the puma gem to production (and maybe test too if it suits your needs) environments only.
# Gemfile
group :test, :production do
gem 'puma'
end
Then run bundle install --without test production.

Puma deployment issue with Heroku

I'm trying to deploy my application to Heroku using Puma. This is my first time using Puma, as this is my first attempt at a "production quality" application. I've added puma as described in the dev center but I'm running into a no method error once deployed. Here's my error from the logs: config/puma.rb:5:in _load_from': undefined method preload_app!' for #<Puma::Configuration::DSL:0x007f89e2686140> (NoMethodError)
I used the suggested configuration in my config\puma.rb:
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['MAX_THREADS'] || 5)
threads threads_count, threads_count
preload_app!
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'
on_worker_boot do
# Worker specific setup for Rails 4.1+
# See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot
ActiveRecord::Base.establish_connection
end
as shown in the error above, it seems Heroku has a problem with the preload_app! command. I'm stuck and don't know where to go from here - I have a feeling I somehow miscreated the file - i.e. I just made a new file in my editor rather than from the command line.
This is how we set config/puma.rb up on Heroku using Rails 4.1.0
workers Integer(ENV['PUMA_WORKERS'] || 3)
threads Integer(ENV['MIN_THREADS'] || 1), Integer(ENV['MAX_THREADS'] || 16)
preload_app!
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'
on_worker_boot do
# worker specific setup
ActiveSupport.on_load(:active_record) do
config = ActiveRecord::Base.configurations[Rails.env] ||
Rails.application.config.database_configuration[Rails.env]
config['pool'] = ENV['MAX_THREADS'] || 16
ActiveRecord::Base.establish_connection(config)
end
end
We keep the workers and threads to a minimum (we are on the free plan).
When I restart our dyno, I get this output in the logs:
2015-03-.. app[web.1]: [3] Puma starting in cluster mode...
2015-03-... app[web.1]: [3] * Version 2.9.1 (ruby 2.1.5-p273), codename: Team High Five
2015-03-... app[web.1]: [3] * Min threads: 1, max threads: 3
2015-03-... app[web.1]: [3] * Environment: production
2015-03-... app[web.1]: [3] * Process workers: 2
2015-03-... app[web.1]: [3] * Preloading application

Resources