diff options
author | Eric Wong <e@80x24.org> | 2013-10-24 22:11:17 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2013-10-24 22:51:55 +0000 |
commit | 7d6ac0c17eb29a00a5b74099dbb3d4d015999f27 (patch) | |
tree | 27229beaeb1f6c23b80b4de9d55ad17c51ac93c1 | |
parent | d90eebe1e50e2bdb9632b64591e4b84cbc0049a1 (diff) | |
download | unicorn-7d6ac0c17eb29a00a5b74099dbb3d4d015999f27.tar.gz |
This will preserve mtime on successful renames for comparisions. While we're at it, avoid writing the new PID until the listeners are inherited successfully. This can be useful to avoid accidentally clobbering a good PID if binding the listener or building the app (preload_app==true) fails
-rw-r--r-- | lib/unicorn/http_server.rb | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb index bed24d0..cd160c5 100644 --- a/lib/unicorn/http_server.rb +++ b/lib/unicorn/http_server.rb @@ -134,11 +134,22 @@ class Unicorn::HttpServer # Note that signals don't actually get handled until the #join method QUEUE_SIGS.each { |sig| trap(sig) { SIG_QUEUE << sig; awaken_master } } trap(:CHLD) { awaken_master } - self.pid = config[:pid] + + # write pid early for Mongrel compatibility if we're not inheriting sockets + # This was needed for compatibility with some health checker a long time + # ago. This unfortunately has the side effect of clobbering valid PID + # files. + self.pid = config[:pid] unless ENV["UNICORN_FD"] self.master_pid = $$ build_app! if preload_app bind_new_listeners! + + # Assuming preload_app==false, we drop the pid file after the app is ready + # to process requests. If binding or build_app! fails with + # preload_app==true, we'll never get here and the parent will recover + self.pid = config[:pid] if ENV["UNICORN_FD"] + spawn_missing_workers self end @@ -180,6 +191,21 @@ class Unicorn::HttpServer Unicorn::HttpRequest::DEFAULTS["rack.logger"] = @logger = obj end + def clobber_pid(path) + unlink_pid_safe(@pid) if @pid + if path + fp = begin + tmp = "#{File.dirname(path)}/#{rand}.#$$" + File.open(tmp, File::RDWR|File::CREAT|File::EXCL, 0644) + rescue Errno::EEXIST + retry + end + fp.syswrite("#$$\n") + File.rename(fp.path, path) + fp.close + end + end + # sets the path for the PID file of the master process def pid=(path) if path @@ -194,18 +220,18 @@ class Unicorn::HttpServer "(or pid=#{path} is stale)" end end - unlink_pid_safe(pid) if pid - if path - fp = begin - tmp = "#{File.dirname(path)}/#{rand}.#$$" - File.open(tmp, File::RDWR|File::CREAT|File::EXCL, 0644) - rescue Errno::EEXIST - retry + # rename the old pid if posible + if @pid && path + begin + File.rename(@pid, path) + rescue Errno::ENOENT, Errno::EXDEV + # a user may have accidentally removed the original. + # Obviously cross-FS renames + clobber_pid(path) end - fp.syswrite("#$$\n") - File.rename(fp.path, path) - fp.close + else + clobber_pid(path) end @pid = path end |