Browse files

Switch web server from Thin to Unicorn

As the Rails application scales to more Heroku dynos, a lack of
concurrency can result in [poor performance](1) and an over-provisioning
of resources. Modifying the app to handle requests more efficiently is
a simple process with immediate benefits.

Unicorn is a [concurrent web server](2) that spawns several processes
within a single dyno without requiring concurrency or threading
awareness in your app.  Applications that migrate to Unicorn often
require fewer dynos and see increased performance.

The [config/unicorn.rb file](3) specifies the number of concurrent web
processes to run on each dyno as well as the proper forking and
termination behavior.

  • Loading branch information...
1 parent 3c58a25 commit d4dfb840a0a64f483ec9fcb99f49518800362255 @croaky croaky committed Apr 5, 2013
4 lib/suspenders/app_builder.rb
@@ -195,6 +195,10 @@ def generate_clearance
generate 'clearance:install'
+ def configure_unicorn
+ copy_file 'unicorn.rb', 'config/unicorn.rb'
+ end
def setup_foreman
copy_file 'sample.env', '.sample.env'
copy_file 'Procfile', 'Procfile'
1 lib/suspenders/generators/app_generator.rb
@@ -120,6 +120,7 @@ def configure_app
build :disable_xml_params
build :add_email_validator
build :setup_default_rake_task
+ build :configure_unicorn
build :setup_foreman
2 templates/Gemfile_clean
@@ -11,7 +11,7 @@ gem 'rails', '>= 3.2.11'
gem 'recipient_interceptor'
gem 'simple_form'
gem 'strong_parameters'
-gem 'thin'
+gem 'unicorn'
group :assets do
gem 'coffee-rails'
2 templates/Procfile
@@ -1 +1 @@
-web: bundle exec rails server thin -p $PORT -e $RACK_ENV
+web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
24 templates/unicorn.rb
@@ -0,0 +1,24 @@
+worker_processes (ENV['WEB_CONCURRENCY'] || 3).to_i
+timeout (ENV['WEB_TIMEOUT'] || 15).to_i
+preload_app true
+before_fork do |server, worker|
+ Signal.trap 'TERM' do
+ puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
+ Process.kill 'QUIT',
+ end
+ if defined? ActiveRecord::Base
+ ActiveRecord::Base.connection.disconnect!
+ end
+after_fork do |server, worker|
+ Signal.trap 'TERM' do
+ puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT'
+ end
+ if defined? ActiveRecord::Base
+ ActiveRecord::Base.establish_connection
+ end

0 comments on commit d4dfb84

Please sign in to comment.