Skip to content

Commit

Permalink
v0.4.0 Kill processes from a thread
Browse files Browse the repository at this point in the history
  • Loading branch information
jclem committed Mar 12, 2013
1 parent f4f5269 commit 51547d9
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 15 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
Kazuki Ohta <kazuki.ohta _at_ gmail.com>
Sadayuki FURUHASHI <frsyuki _at_ gmail.com>
Jonathan Clem <jonathan _at_ jclem.net>
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
Release 0.4.0 - 2013/03/12
* Send signals from inside a Thread (required for QUIT signal)
* Fix broken if/else in kill_self

Release 0.3.6 - 2013/03/09
* do not require configuration
* fix missing randomize() in MaxRequests killer
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.3.6
0.4.0
35 changes: 23 additions & 12 deletions lib/unicorn/worker_killer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,31 @@ class << self
# @see http://unicorn.bogomips.org/SIGNALS.html
def self.kill_self(logger, start_time)
alive_sec = (Time.now - start_time).to_i
worker_pid = Process.pid

i = 0
while true
i += 1
sig = :QUIT
if i > configuration.max_quit
sig = :TERM
elsif i > configuration.max_term
sig = :KILL
end
Thread.new do
i = 0

while pid_exist?(worker_pid)
i += 1

sig = :QUIT
sig = :TERM if i > configuration.max_quit
sig = :KILL if i > configuration.max_term

logger.warn "#{self} send SIG#{sig} (pid: #{Process.pid}) alive: #{alive_sec} sec (trial #{i})"
Process.kill sig, Process.pid
logger.warn "#{self} send SIG#{sig} (pid: #{worker_pid}) alive: #{alive_sec} sec (trial #{i})"
Process.kill sig, worker_pid

sleep configuration.sleep_interval
sleep configuration.sleep_interval
end
end
end

def self.pid_exist?(pid)
Process.getpgid(pid)
rescue Errno::ESRCH
end

module Oom
# Killing the process must be occurred at the outside of the request. We're
# using similar techniques used by OobGC, to ensure actual killing doesn't
Expand All @@ -52,11 +59,13 @@ def randomize(integer)

def process_client(client)
super(client) # Unicorn::HttpServer#process_client

return if @_worker_memory_limit_min == 0 && @_worker_memory_limit_max == 0

@_worker_process_start ||= Time.now
@_worker_memory_limit ||= @_worker_memory_limit_min + randomize(@_worker_memory_limit_max - @_worker_memory_limit_min + 1)
@_worker_check_count += 1

if @_worker_check_count % @_worker_check_cycle == 0
rss = _worker_rss()
if rss > @_worker_memory_limit
Expand Down Expand Up @@ -112,6 +121,7 @@ def self.new(app, max_requests_min = 3072, max_requests_max = 4096)
s.instance_variable_set(:@_worker_max_requests_min, max_requests_min)
s.instance_variable_set(:@_worker_max_requests_max, max_requests_max)
end

app # pretend to be Rack middleware since it was in the past
end

Expand All @@ -126,6 +136,7 @@ def process_client(client)
@_worker_process_start ||= Time.now
@_worker_cur_requests ||= @_worker_max_requests_min + randomize(@_worker_max_requests_max - @_worker_max_requests_min + 1)
@_worker_max_requests ||= @_worker_cur_requests

if (@_worker_cur_requests -= 1) <= 0
logger.warn "#{self}: worker (pid: #{Process.pid}) exceeds max number of requests (limit: #{@_worker_max_requests})"
Unicorn::WorkerKiller.kill_self(logger, @_worker_process_start)
Expand Down
4 changes: 2 additions & 2 deletions unicorn-worker-killer.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ Gem::Specification.new do |gem|
gem.homepage = "https://github.com/kzk/unicorn-worker-killer"
gem.summary = gem.description
gem.version = File.read("VERSION").strip
gem.authors = ["Kazuki Ohta", "Sadayuki Furuhashi"]
gem.email = ["kazuki.ohta@gmail.com", "frsyuki@gmail.com"]
gem.authors = ["Kazuki Ohta", "Sadayuki Furuhashi", "Jonathan Clem"]
gem.email = ["kazuki.ohta@gmail.com", "frsyuki@gmail.com", "jonathan@jclem.net"]
gem.has_rdoc = false
#gem.platform = Gem::Platform::RUBY
gem.files = `git ls-files`.split("\n")
Expand Down

0 comments on commit 51547d9

Please sign in to comment.