class StripMem::App

Attributes

command[R]
start_time[R]

Public Class Methods

new(argv) click to toggle source
# File lib/stripmem/app.rb, line 21
def initialize(argv)
  @command = argv
  @start_time = Time.now
end
run!(argv) click to toggle source
# File lib/stripmem/app.rb, line 17
def self.run!(argv)
  new(argv).run!
end

Public Instance Methods

find_children() click to toggle source
# File lib/stripmem/app.rb, line 55
def find_children
  children = `ps a -o ppid=,pid=,command=`.lines.each_with_object(Hash.new { |h,k| h[k] = [] }) { |line, h| (line =~ /(\d+) +(\d+) +(.*)/) && h[$1].push(:pid => $2, :name => $3) }
  parents = processes.keys
  while parent = parents.shift
    children[parent.to_s].each do |child|
      if child[:name] !~ /^ps /
        pid = child[:pid].to_i
        parents << pid
        processes[pid] ||= child[:name]
      end
    end
  end
end
kill!() click to toggle source
# File lib/stripmem/app.rb, line 49
def kill!
  Process.kill('QUIT', @child.to_i) unless @child_status
rescue => e
  puts "kill #{@child.inspect}: #{e}"
end
processes() click to toggle source
# File lib/stripmem/app.rb, line 75
def processes
  @processes ||= { $$ => '(stripmem)' }
end
ps(channel) click to toggle source
# File lib/stripmem/app.rb, line 69
def ps(channel)
  ps = `ps -o pid=,rss= -p #{processes.keys.join(',')}`.lines.each_with_object({}) { |line, h| pid, rss = line.split(/\s+/) ; h[pid.to_i] = rss.to_i }
  offset = Time.now - start_time
  channel.push :offset => offset, :samples => processes.map { |pid, name| { :name => "[#{pid}] #{name}", :rss => ps[pid] } }
end
run!() click to toggle source
# File lib/stripmem/app.rb, line 28
def run!
  @timers = []
  EventMachine.run do
    spawn!
    channel = EM::Channel.new
    @timers = [
      EM::PeriodicTimer.new(1.0) { find_children },
      EM::PeriodicTimer.new(0.2) { ps(channel) },
      EM::PeriodicTimer.new(1.0) { wait_child },
    ]
    WebSocket.new(channel).run!
    Thread.new do
      Web.new(channel).run! # This doesn't return until sinatra exits. (Sinatra handles SIGINT.)
      kill!
      EM.stop
      exit
    end
  end
  kill!
end
spawn!() click to toggle source
# File lib/stripmem/app.rb, line 79
def spawn!
  @child = fork do
    exec(*command)
  end
  processes[@child] = command.join(' ')
end
wait_child() click to toggle source
# File lib/stripmem/app.rb, line 86
def wait_child
  if @child_status ||= Process.waitpid2(-1, Process::WNOHANG)
    @timers.each do |timer|
      timer.cancel
    end
  end
end