darcy
9/8/2010 - 7:54 PM

gistfile1.txt

require 'sys/proctable'
module Unicorn
  
  class OnMaxHeap < Struct.new(:max_rss, :max_vsize)
    include OobGCCondition
    include Sys

    def initialize(max_rss = nil, max_vsize = nil)
      %w( rss vsize ).each do |required_mem_field|
        raise "sys/proctable doesn't support required memory fields on this platform" unless ProcTable.fields.include?(required_mem_field)
      end
      super(max_rss, max_vsize)
    end
  
    def should_gc(caller = nil)
      p = ProcTable.ps(Process.id)
      return true if max_rss and p.rss > max_rss
      return true if max_vsize and p.vsize > max_vsize
      false
    end
    
    def after_gc(caller = nil)
      p = ProcTable.ps(Process.id)
      suicide("max_rss still above max after GC") if max_rss and p.rss > max_rss
      suicide("max_vsize still above max after GC") if max_vsize and p.vsize > max_vsize
    end
    
    private
    def suicide(reason)
      $stderr.puts "INFO: #{reason}, restarting worker"
      Process.kill "QUIT", Process.pid
    end
  end
  
end