1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Add Default Puma Config

When the `puma` command is run without any configuration options it will detect presence of a `config/puma.rb` file and use that. Currently there is discrepancy between `puma` command and `rails server` but Evan said it would be reasonable to add in reading in config from the default location. I am working on that right now as a feature in puma/puma.

Why do we need this? By default Puma uses 16 threads, and by default ActiveRecord only has 5 threads. Due to the architecture of AR it is guaranteed that if you're running with fewer DB connections than your server has threads you will hit `ActiveRecord::ConnectionTimeoutError ` eventually if your app gets modest amounts of traffic. Since we are providing a default webserver, we should provide reasonable configuration for that webserver.

This PR does a few things, first it sets the default Puma thread count to 5 to mach ActiveRecord's default. It sets the default environment to `"development"` and the default port to 300 so that booting the server with `$ puma` will give you the same default port as `rails server`. It is worth mentioning that by reading in from `PORT` environment variable this config can work with containerized deployments, such as on Heroku. 

We are not using worker processes by default, that way JRuby and windows devs can use this configuration without modification. I went ahead and included a default `on_worker_boot`. It won't be used unless a worker count is specified, that means this config will not use it. Even though it's not being used now It will make someone who wants to try modifying their config to run extra workers easier.

cc/ @pixeltrix
This commit is contained in:
schneems 2016-01-14 13:05:41 -06:00
parent 9e4534c473
commit 5563c329ee
5 changed files with 64 additions and 3 deletions

View file

@ -51,6 +51,9 @@ module Rails
class_option :skip_active_record, type: :boolean, aliases: '-O', default: false, class_option :skip_active_record, type: :boolean, aliases: '-O', default: false,
desc: 'Skip Active Record files' desc: 'Skip Active Record files'
class_option :skip_puma, type: :boolean, aliases: '-P', default: false,
desc: 'Skip Puma related files'
class_option :skip_action_cable, type: :boolean, aliases: '-C', default: false, class_option :skip_action_cable, type: :boolean, aliases: '-C', default: false,
desc: 'Skip Action Cable files' desc: 'Skip Action Cable files'
@ -113,6 +116,7 @@ module Rails
def gemfile_entries def gemfile_entries
[rails_gemfile_entry, [rails_gemfile_entry,
database_gemfile_entry, database_gemfile_entry,
webserver_gemfile_entry,
assets_gemfile_entry, assets_gemfile_entry,
javascript_gemfile_entry, javascript_gemfile_entry,
jbuilder_gemfile_entry, jbuilder_gemfile_entry,
@ -171,6 +175,12 @@ module Rails
"Use #{options[:database]} as the database for Active Record" "Use #{options[:database]} as the database for Active Record"
end end
def webserver_gemfile_entry
return [] if options[:skip_puma]
comment = 'Use Puma as the app server'
GemfileEntry.new('puma', nil, comment)
end
def include_all_railties? def include_all_railties?
options.values_at(:skip_active_record, :skip_action_mailer, :skip_test, :skip_sprockets, :skip_action_cable).none? options.values_at(:skip_active_record, :skip_action_mailer, :skip_test, :skip_sprockets, :skip_action_cable).none?
end end

View file

@ -79,6 +79,7 @@ module Rails
template "environment.rb" template "environment.rb"
template "secrets.yml" template "secrets.yml"
template "cable.yml" unless options[:skip_action_cable] template "cable.yml" unless options[:skip_action_cable]
template "puma.rb" unless options[:skip_puma]
directory "environments" directory "environments"
directory "initializers" directory "initializers"

View file

@ -12,9 +12,6 @@ source 'https://rubygems.org'
<% end -%> <% end -%>
<% end -%> <% end -%>
# Use Puma as the app server
gem 'puma'
# Use ActiveModel has_secure_password # Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7' # gem 'bcrypt', '~> 3.1.7'

View file

@ -0,0 +1,44 @@
# Puma can serve each request in a thread from an internal thread pool.
# The `threads` method setting takes two numbers a minimum and maximum.
# Any libraries that use thread pools should be configured to match
# the maximum value specified for Puma. Default is set to 5 threads for minimum
# and maximum, this matches the default thread size of Active Record.
#
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i
threads threads_count, threads_count
# Specifies the `port` that Puma will listen on to receive requests, default is 3000.
#
port ENV.fetch("PORT") { 3000 }
# Specifies the `environment` that Puma will run in.
#
environment ENV.fetch("RAILS_ENV") { "development" }
# Specifies the number of `workers` to boot in clustered mode.
# Workers are forked webserver processes. If using threads and workers together
# the concurrency of the application would be max `threads` * `workers`.
# Workers do not work on JRuby or Windows (both of which do not support
# processes).
#
# workers ENV.fetch("WEB_CONCURRENCY") { 2 }
# Use the `preload_app!` method when specifying a `workers` number.
# This directive tells Puma to first boot the application and load code
# before forking the application. This takes advantage of Copy On Write
# process behavior so workers use less memory. If you use this option
# you need to make sure to reconnect any threads in the `on_worker_boot`
# block.
#
# preload_app!
# The code in the `on_worker_boot` will be called if you are using
# clustered mode by specifying a number of `workers`. After each worker
# process is booted this block will be run, if you are using `preload_app!`
# option you will want to use this block to reconnect to any threads
# or connections that may have been created at application boot, Ruby
# cannot share connections between processes.
#
# on_worker_boot do
# ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
# end

View file

@ -27,6 +27,7 @@ DEFAULT_APP_FILES = %w(
config/initializers config/initializers
config/locales config/locales
config/cable.yml config/cable.yml
config/puma.rb
db db
lib lib
lib/tasks lib/tasks
@ -337,6 +338,14 @@ class AppGeneratorTest < Rails::Generators::TestCase
end end
end end
def test_generator_if_skip_puma_is_given
run_generator [destination_root, "--skip-puma"]
assert_no_file "config/puma.rb"
assert_file "Gemfile" do |content|
assert_no_match(/puma/, content)
end
end
def test_generator_if_skip_active_record_is_given def test_generator_if_skip_active_record_is_given
run_generator [destination_root, "--skip-active-record"] run_generator [destination_root, "--skip-active-record"]
assert_no_file "config/database.yml" assert_no_file "config/database.yml"