Sha256: 6b4851646e97d562e488b53da60589b30a8965fb6247927d247dd182a4115789

Contents?: true

Size: 1.41 KB

Versions: 1

Compression:

Stored size: 1.41 KB

Contents

module PumaWorkerKiller
  class Reaper
    def initialize(max_ram, master = self.get_master)
      @max_ram = max_ram
      @master  = master
    end

    def get_master
      ObjectSpace.each_object(Puma::Cluster).map { |obj| obj }.first
    end

    def get_memory(pid)
      GetProcessMem.new(pid).mb
    end

    def get_workers
      workers = {}
      @master.instance_variable_get("@workers").each { |worker| workers[worker] = get_memory(worker.pid) }
      workers
    end

    def get_total_memory(workers = self.get_workers)
      master_memory = get_memory(Process.pid)
      worker_memory = workers.map {|_, mem| mem }.inject(&:+) || 0
      worker_memory + master_memory
    end

    def wait(pid)
      Process.wait(pid)
    rescue Errno::ECHILD
    end

    def reap
      return false unless @master
      workers      = get_workers
      total_memory = get_total_memory(workers)
      if workers.any? && total_memory > @max_ram
        biggest_worker, memory_used = workers.sort_by {|_, mem| mem }.last
        biggest_worker.term
        @master.log "PumaWorkerKiller: Out of memory. #{workers.count} workers consuming total: #{total_memory} mb out of max: #{@max_ram} mb. Sending TERM to #{biggest_worker.inspect} consuming #{memory_used} mb."
        wait(biggest_worker.pid)
      else
        @master.log "PumaWorkerKiller: Consuming #{total_memory} mb with master and #{workers.count} workers"
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
puma_worker_killer-0.0.1 lib/puma_worker_killer/reaper.rb