Hi, I''ve just started using Unicorn in production behind Nginx with a Rails app, for the most part its been a smooth transition apart from this one issue. When I do an?in place?restart (USR2), the restart process works but the workers load my old Rails release, not the new one. I''m guessing that because the master process is currently in the old release directory, when I signal USR2 it''s just reloading inside the current directory. I''m deploying with Capistrano, so app/current is a symlink to a specific release. I''ve tried changing to the new release directory in before_work but that made no difference. Is there a callback that fires before the master preloads the app? worker_processes 6 preload_app true timeout 60 listen "/tmp/unicorn.production.sock" pid "/tmp/unicorn.production.pid" before_fork do |server, worker| ??Dir.chdir("/var/www/apps/systino_production/current") ??old_pid = "/tmp/unicorn.#{RAILS_ENV}.pid.oldbin" ??if File.exists?(old_pid) && server.pid != old_pid ?? ?begin ?? ? ?Process.kill("QUIT", File.read(old_pid).to_i) ?? ?rescue Errno::ENOENT, Errno::ESRCH ?? ? ?# someone else did our job for us ?? ?end ??end end after_fork do |server, worker| ??ActiveRecord::Base.establish_connection end I also have a little launcher script (I''m using Solaris - SMF doesn''t let me provide a custom restart routine, so I have to bypass it and use this script): #!/usr/bin/ruby $rails_env = ARGV[0] $pid_file = "/tmp/unicorn.#{$rails_env}.pid" def restart(pid) ??system("kill -USR2 #{pid}") end def start ??system("/opt/local/bin/unicorn_rails -c config/unicorn.rb -E #{$rails_env} -D") end if File.exists?($pid_file) ??pid = File.read($pid_file).strip.to_i ??begin ?? ?Process.kill(0, pid) ??rescue Errno::ESRCH ?? ?# Not running ?? ?start ??else ?? ?restart(pid) ??end else ??start end At the end of the deploy I execute: task :restart_unicorn do ??run "cd #{current_path}; ruby config/unicorn_launcher.rb #{rails_env}" end
Ian Leitch <port001 at gmail.com> wrote:> Hi, > > I''ve just started using Unicorn in production behind Nginx with a > Rails app, for the most part its been a smooth transition apart from > this one issue. > When I do an?in place?restart (USR2), the restart process works but > the workers load my old Rails release, not the new one. I''m guessing > that because the master process is currently in the old release > directory, when I signal USR2 it''s just reloading inside the current > directory. I''m deploying with Capistrano, so app/current is a symlink > to a specific release. I''ve tried changing to the new release > directory in before_work but that made no difference. Is there a > callback that fires before the master preloads the app?Hi Ian, Unicorn chdirs to the directory returned by `/bin/sh -c pwd` when it was originally started. The output of `pwd` *should* be symlink-aware, but then Solaris /bin/sh is weird. Can you confirm that it''s broken? You can put the following in your config (outside of the hooks): app_root = "/var/www/apps/systino_production/current" Dir.chdir(Unicorn::HttpServer::START_CTX[:cwd] = app_root) I''ve been pondering adding a "working_directory" directive to Configurator, too. However the START_CTX hash is considered a stable interface and I recently documented it in http://unicorn.bogomips.org/Unicorn.html START_CTX even allows you to switch between different installation paths for Unicorn[1] and alter command line options that were originally passed. Lots of rope there :> [1] for different Ruby installs/versions, or even swap in Rainbows! or vice versa -- Eric Wong
Apologies for the noise, I discovered START_CTX[:cwd] and that fixed it. Solaris sh is indeed the culprit: $ cd /var/www/apps/production/current (admin at production:/var/www/apps/production/current) $ sh -c pwd /var/www/apps/production/releases/20091026160154 Thanks for creating Unicorn! 2009/10/26 Eric Wong <normalperson at yhbt.net>:> Ian Leitch <port001 at gmail.com> wrote: >> Hi, >> >> I''ve just started using Unicorn in production behind Nginx with a >> Rails app, for the most part its been a smooth transition apart from >> this one issue. >> When I do an?in place?restart (USR2), the restart process works but >> the workers load my old Rails release, not the new one. I''m guessing >> that because the master process is currently in the old release >> directory, when I signal USR2 it''s just reloading inside the current >> directory. I''m deploying with Capistrano, so app/current is a symlink >> to a specific release. I''ve tried changing to the new release >> directory in before_work but that made no difference. Is there a >> callback that fires before the master preloads the app? > > Hi Ian, > > Unicorn chdirs to the directory returned by `/bin/sh -c pwd` when it was > originally started. ?The output of `pwd` *should* be symlink-aware, but > then Solaris /bin/sh is weird. ?Can you confirm that it''s broken? > > You can put the following in your config (outside of the hooks): > > ?app_root = "/var/www/apps/systino_production/current" > ?Dir.chdir(Unicorn::HttpServer::START_CTX[:cwd] = app_root) > > I''ve been pondering adding a "working_directory" directive to > Configurator, too. ?However the START_CTX hash is considered a stable > interface and I recently documented it in > http://unicorn.bogomips.org/Unicorn.html > > START_CTX even allows you to switch between different installation paths > for Unicorn[1] and alter command line options that were originally > passed. ?Lots of rope there :> > > [1] for different Ruby installs/versions, > ? ?or even swap in Rainbows! or vice versa > > -- > Eric Wong > _______________________________________________ > mongrel-unicorn mailing list > mongrel-unicorn at rubyforge.org > http://rubyforge.org/mailman/listinfo/mongrel-unicorn >