Class: StripMem::App

Inherits:
Object
  • Object
show all
Defined in:
lib/stripmem/app.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(argv) ⇒ App

Returns a new instance of App.



10
11
12
13
# File 'lib/stripmem/app.rb', line 10

def initialize(argv)
  @command = argv
  @start_time = Time.now
end

Instance Attribute Details

#commandObject (readonly)

Returns the value of attribute command.



15
16
17
# File 'lib/stripmem/app.rb', line 15

def command
  @command
end

#start_timeObject (readonly)

Returns the value of attribute start_time.



15
16
17
# File 'lib/stripmem/app.rb', line 15

def start_time
  @start_time
end

Class Method Details

.run!(argv) ⇒ Object



6
7
8
# File 'lib/stripmem/app.rb', line 6

def self.run!(argv)
  new(argv).run!
end

Instance Method Details

#find_childrenObject



36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/stripmem/app.rb', line 36

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

#processesObject



56
57
58
# File 'lib/stripmem/app.rb', line 56

def processes
  @processes ||= { $$ => '(stripmem)' }
end

#ps(channel) ⇒ Object



50
51
52
53
54
# File 'lib/stripmem/app.rb', line 50

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!Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/stripmem/app.rb', line 17

def run!
  EventMachine.run do
    spawn!
    channel = EM::Channel.new
    EM::PeriodicTimer.new(1.0) { find_children }
    EM::PeriodicTimer.new(0.2) { ps(channel) }
    WebSocket.new(channel).run!
    Thread.new do
      Web.new(channel).run! # This doesn't return until sinatra exits. (Sinatra handles SIGINT.)
      EM.stop
    end
  end
  begin
    Process.kill(@child, 'QUIT')
  rescue => e
    puts "kill #{@child.inspect}: #{e}"
  end
end

#spawn!Object



60
61
62
63
64
65
# File 'lib/stripmem/app.rb', line 60

def spawn!
  @child = fork do
    exec(*command)
  end
  processes[@child] = command.join(' ')
end