aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorschneems <richard.schneeman@gmail.com>2016-01-14 13:05:41 -0600
committerschneems <richard.schneeman@gmail.com>2016-01-29 15:58:37 -0600
commit5563c329eee5febc22a3330e16fe8a6899d42fe2 (patch)
treea62ef71a36c3f90ca58341a6f01e81da86c99be7
parent9e4534c4730b8e8ed5c249d4bf3527fb597a1a98 (diff)
downloadrails-5563c329eee5febc22a3330e16fe8a6899d42fe2.tar.gz
rails-5563c329eee5febc22a3330e16fe8a6899d42fe2.tar.bz2
rails-5563c329eee5febc22a3330e16fe8a6899d42fe2.zip
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
-rw-r--r--railties/lib/rails/generators/app_base.rb10
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb1
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile3
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/puma.rb44
-rw-r--r--railties/test/generators/app_generator_test.rb9
5 files changed, 64 insertions, 3 deletions
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
index c629459d95..420e9673a1 100644
--- a/railties/lib/rails/generators/app_base.rb
+++ b/railties/lib/rails/generators/app_base.rb
@@ -51,6 +51,9 @@ module Rails
class_option :skip_active_record, type: :boolean, aliases: '-O', default: false,
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,
desc: 'Skip Action Cable files'
@@ -113,6 +116,7 @@ module Rails
def gemfile_entries
[rails_gemfile_entry,
database_gemfile_entry,
+ webserver_gemfile_entry,
assets_gemfile_entry,
javascript_gemfile_entry,
jbuilder_gemfile_entry,
@@ -171,6 +175,12 @@ module Rails
"Use #{options[:database]} as the database for Active Record"
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?
options.values_at(:skip_active_record, :skip_action_mailer, :skip_test, :skip_sprockets, :skip_action_cable).none?
end
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index 3d689ff37e..63bb02cf9a 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -79,6 +79,7 @@ module Rails
template "environment.rb"
template "secrets.yml"
template "cable.yml" unless options[:skip_action_cable]
+ template "puma.rb" unless options[:skip_puma]
directory "environments"
directory "initializers"
diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile
index da5af4eefc..3825dc4e38 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile
@@ -12,9 +12,6 @@ source 'https://rubygems.org'
<% end -%>
<% end -%>
-# Use Puma as the app server
-gem 'puma'
-
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
diff --git a/railties/lib/rails/generators/rails/app/templates/config/puma.rb b/railties/lib/rails/generators/rails/app/templates/config/puma.rb
new file mode 100644
index 0000000000..1bf274bc66
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/config/puma.rb
@@ -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
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index 5b62b500e5..39224b70ca 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -27,6 +27,7 @@ DEFAULT_APP_FILES = %w(
config/initializers
config/locales
config/cable.yml
+ config/puma.rb
db
lib
lib/tasks
@@ -337,6 +338,14 @@ class AppGeneratorTest < Rails::Generators::TestCase
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
run_generator [destination_root, "--skip-active-record"]
assert_no_file "config/database.yml"