Permalink
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.

[1] https://blog.heroku.com/archives/2013/2/16/routing_performance_update
[2] https://blog.heroku.com/archives/2013/2/27/unicorn_rails
[3] https://devcenter.heroku.com/articles/rails-unicorn#adding-unicorn-to-your-application
  • Loading branch information...
1 parent 3c58a25 commit e1ff44bfa2d8bc1db5570c465051cc36095815aa @croaky croaky committed Apr 5, 2013
@@ -195,6 +195,10 @@ def generate_clearance
generate 'clearance:install'
end
+ def configure_unicorn
+ copy_file 'unicorn.rb', 'config/unicorn.rb'
+ end
+
def setup_foreman
copy_file 'sample.env', '.sample.env'
copy_file 'Procfile', 'Procfile'
@@ -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
end
@@ -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'
View
@@ -1 +1 @@
-web: bundle exec rails server thin -p $PORT -e $RACK_ENV
+web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
View
@@ -0,0 +1,26 @@
+# https://devcenter.heroku.com/articles/rails-unicorn
+
+worker_processes (ENV['WEB_CONCURRENCY'] || 3).to_i
+timeout (ENV['WEB_TIMEOUT'] || 5).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', Process.pid
+ end
+
+ if defined? ActiveRecord::Base
+ ActiveRecord::Base.connection.disconnect!
+ end
+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
+end

0 comments on commit e1ff44b

Please sign in to comment.