Skip to content

Commit

Permalink
Refactor memory code into separate gem
Browse files Browse the repository at this point in the history
Love the idea here, I was able to generalize the memory grabbing code into a gem here: https://github.com/schneems/get_process_mem

It would be nice if we could use this code outside of Unicorn-worker-killer as well as reduce the amount of code that must be maintained directly in this library.
  • Loading branch information
schneems committed Feb 9, 2014
1 parent 09cd6fa commit f5a401a
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 35 deletions.
36 changes: 2 additions & 34 deletions lib/unicorn/worker_killer.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'unicorn/configuration'
require 'get_process_mem'

module Unicorn::WorkerKiller
class << self
Expand Down Expand Up @@ -54,9 +55,8 @@ def process_client(client)
@_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()
rss = GetProcessMem.new.bytes
logger.info "#{self}: worker (pid: #{Process.pid}) using #{rss} bytes." if @_verbose
if rss > @_worker_memory_limit
logger.warn "#{self}: worker (pid: #{Process.pid}) exceeds memory limit (#{rss} bytes > #{@_worker_memory_limit} bytes)"
Expand All @@ -65,38 +65,6 @@ def process_client(client)
@_worker_check_count = 0
end
end

private

def _worker_rss
proc_status = "/proc/#{Process.pid}/status"
if File.exists? proc_status
open(proc_status).each_line { |l|
if l.include? 'VmRSS'
ls = l.split
if ls.length == 3
value = ls[1].to_i
unit = ls[2]
case unit.downcase
when 'kb'
return value*(1024**1)
when 'mb'
return value*(1024**2)
when 'gb'
return value*(1024**3)
end
end
end
}
end

# Forking the child process sometimes fails under low memory condition.
# It would be ideal for not forking the process to get RSS. For Linux,
# this module reads '/proc/<pid>/status' to get RSS, but not for other
# environments (e.g. MacOS and Windows).
kb = `ps -o rss= -p #{Process.pid}`.to_i
return kb * 1024
end
end

module MaxRequests
Expand Down
3 changes: 2 additions & 1 deletion unicorn-worker-killer.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Gem::Specification.new do |gem|
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
gem.require_paths = ['lib']
gem.add_dependency "unicorn", "~> 4"
gem.add_dependency "unicorn", "~> 4"
gem.add_dependency "get_process_mem", "~> 0"
gem.add_development_dependency "rake", ">= 0.9.2"
end

0 comments on commit f5a401a

Please sign in to comment.