Class: MemoryMonitor
- Inherits:
-
Object
- Object
- MemoryMonitor
- Defined in:
- lib/memory_monitor.rb,
lib/memory_monitor/version.rb
Constant Summary collapse
- SIGNALS =
%w(HUP INT QUIT USR1 USR2 TERM)
- VERSION =
"0.1.0"
Instance Attribute Summary collapse
-
#command ⇒ Object
readonly
Returns the value of attribute command.
-
#interval ⇒ Object
readonly
Returns the value of attribute interval.
-
#limit ⇒ Object
readonly
Returns the value of attribute limit.
-
#memory_in_kilobytes ⇒ Object
readonly
Returns the value of attribute memory_in_kilobytes.
-
#memory_in_megabytes ⇒ Object
readonly
Returns the value of attribute memory_in_megabytes.
-
#pgid ⇒ Object
readonly
Returns the value of attribute pgid.
-
#pid ⇒ Object
readonly
Returns the value of attribute pid.
-
#timeout ⇒ Object
readonly
Returns the value of attribute timeout.
Class Method Summary collapse
Instance Method Summary collapse
- #forward_signals ⇒ Object
-
#initialize(command, limit:, timeout: 2, interval: 1) ⇒ MemoryMonitor
constructor
A new instance of MemoryMonitor.
- #kill ⇒ Object
- #limit_in_kilobytes ⇒ Object
- #log(message) ⇒ Object
- #monitor ⇒ Object
- #run ⇒ Object
- #term ⇒ Object
Constructor Details
#initialize(command, limit:, timeout: 2, interval: 1) ⇒ MemoryMonitor
Returns a new instance of MemoryMonitor.
13 14 15 16 17 18 |
# File 'lib/memory_monitor.rb', line 13 def initialize(command, limit:, timeout: 2, interval: 1) @command = command @limit = limit @timeout = timeout @interval = interval end |
Instance Attribute Details
#command ⇒ Object (readonly)
Returns the value of attribute command.
4 5 6 |
# File 'lib/memory_monitor.rb', line 4 def command @command end |
#interval ⇒ Object (readonly)
Returns the value of attribute interval.
4 5 6 |
# File 'lib/memory_monitor.rb', line 4 def interval @interval end |
#limit ⇒ Object (readonly)
Returns the value of attribute limit.
4 5 6 |
# File 'lib/memory_monitor.rb', line 4 def limit @limit end |
#memory_in_kilobytes ⇒ Object (readonly)
Returns the value of attribute memory_in_kilobytes.
4 5 6 |
# File 'lib/memory_monitor.rb', line 4 def memory_in_kilobytes @memory_in_kilobytes end |
#memory_in_megabytes ⇒ Object (readonly)
Returns the value of attribute memory_in_megabytes.
4 5 6 |
# File 'lib/memory_monitor.rb', line 4 def memory_in_megabytes @memory_in_megabytes end |
#pgid ⇒ Object (readonly)
Returns the value of attribute pgid.
4 5 6 |
# File 'lib/memory_monitor.rb', line 4 def pgid @pgid end |
#pid ⇒ Object (readonly)
Returns the value of attribute pid.
4 5 6 |
# File 'lib/memory_monitor.rb', line 4 def pid @pid end |
#timeout ⇒ Object (readonly)
Returns the value of attribute timeout.
4 5 6 |
# File 'lib/memory_monitor.rb', line 4 def timeout @timeout end |
Class Method Details
.run(*args) ⇒ Object
9 10 11 |
# File 'lib/memory_monitor.rb', line 9 def self.run(*args) new(*args).run end |
Instance Method Details
#forward_signals ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/memory_monitor.rb', line 78 def forward_signals SIGNALS.each do |signal| Signal.trap(signal) do begin Process.kill(signal, pid) if pid rescue Errno::ESRCH # pid doesn't exist end end end end |
#kill ⇒ Object
69 70 71 72 |
# File 'lib/memory_monitor.rb', line 69 def kill log "process failed to stop after #{timeout}s, sending SIGKILL" Process.kill("KILL", -pgid) end |
#limit_in_kilobytes ⇒ Object
38 39 40 |
# File 'lib/memory_monitor.rb', line 38 def limit_in_kilobytes limit * 1024 end |
#log(message) ⇒ Object
74 75 76 |
# File 'lib/memory_monitor.rb', line 74 def log() $stderr.puts "[memory_monitor] #{}" end |
#monitor ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/memory_monitor.rb', line 42 def monitor loop do @memory_in_kilobytes = `ps -o pgrp= -o rss=` .split("\n") .map { |line| line.split(" ").map(&:to_i) } .select { |pgid, _| pgid == self.pgid } .map { |_, size| size } .max @memory_in_megabytes = (memory_in_kilobytes / 1024).round(1) if memory_in_kilobytes > limit_in_kilobytes term sleep timeout kill end sleep interval end end |
#run ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/memory_monitor.rb', line 20 def run forward_signals @pid = Process.spawn(*command, pgroup: true) @pgid = Process.getpgid(pid) Thread.abort_on_exception = true Thread.new { monitor } Process.wait pid if $?.success? $?.exitstatus else false end end |
#term ⇒ Object
64 65 66 67 |
# File 'lib/memory_monitor.rb', line 64 def term log "process memory #{memory_in_megabytes}MB exceeded limit #{limit}MB, sending SIGTERM" Process.kill("TERM", -pgid) end |