Permalink
Browse files

Master process catches SIGIO and kills a highest memory worker gracef…

…ully
  • Loading branch information...
1 parent d0b2419 commit a9a8ae3b9bd7a7e84c19a101ff746e07e9566387 @mirakui mirakui committed Apr 17, 2012
Showing with 15 additions and 1 deletion.
  1. +15 −1 lib/unicorn/http_server.rb
View
16 lib/unicorn/http_server.rb
@@ -54,7 +54,7 @@ class Unicorn::HttpServer
SIG_QUEUE = []
# list of signals we care about and trap in master.
- QUEUE_SIGS = [ :WINCH, :QUIT, :INT, :TERM, :USR1, :USR2, :HUP, :TTIN, :TTOU ]
+ QUEUE_SIGS = [ :WINCH, :QUIT, :INT, :TERM, :USR1, :USR2, :HUP, :TTIN, :TTOU, :IO ]
# :startdoc:
# We populate this at startup so we can figure out how to reexecute
@@ -305,6 +305,8 @@ def join
logger.info "config_file not present, reexecuting binary"
reexec
end
+ when :IO
+ kill_fattest_worker(:QUIT)
end
rescue => e
Unicorn.log_error(@logger, "master loop error", e)
@@ -641,6 +643,18 @@ def kill_each_worker(signal)
WORKERS.keys.each { |wpid| kill_worker(signal, wpid) }
end
+ def kill_fattest_worker(signal)
+ proc_rss = Hash[*`ps xo pid,rss`.split[2..-1].map(&:to_i)]
+
+ wpid, max_rss = WORKERS.keys.inject([nil, 0]) do |max, wpid|
+ rss = proc_rss[wpid] || 0
+ @logger.info "[#{wpid}] #{rss}"
+ rss > max[1] ? [wpid, rss] : max
+ end
+ @logger.info "Max VmRss=#{max_rss}, pid=#{wpid}"
+ kill_worker(signal, wpid) if wpid > 0
+ end
+
# unlinks a PID file at given +path+ if it contains the current PID
# still potentially racy without locking the directory (which is
# non-portable and may interact badly with other programs), but the

0 comments on commit a9a8ae3

Please sign in to comment.