Class: ProcessWatcher::Watcher
- Inherits:
-
Object
- Object
- ProcessWatcher::Watcher
- Defined in:
- lib/process_watcher/watcher.rb
Instance Attribute Summary collapse
-
#max_bytes ⇒ Object
readonly
Maximum size in bytes of watched directory before process is killed.
-
#max_seconds ⇒ Object
readonly
Maximum number of elapased seconds before external process is killed.
Instance Method Summary collapse
-
#initialize(max_bytes, max_seconds) ⇒ Watcher
constructor
Initialize attributes.
-
#launch_and_watch(cmd, args, dest_dir) ⇒ Object
Launch given command as external process and watch given directory so it doesn’t exceed given size.
Constructor Details
#initialize(max_bytes, max_seconds) ⇒ Watcher
Initialize attributes
- max_bytes(Integer)
-
Maximum size in bytes of watched directory before process is killed
- max_seconds(Integer)
-
Maximum number of elapased seconds before external process is killed
60 61 62 63 |
# File 'lib/process_watcher/watcher.rb', line 60 def initialize(max_bytes, max_seconds) @max_bytes = max_bytes @max_seconds = max_seconds end |
Instance Attribute Details
#max_bytes ⇒ Object (readonly)
Maximum size in bytes of watched directory before process is killed
53 54 55 |
# File 'lib/process_watcher/watcher.rb', line 53 def max_bytes @max_bytes end |
#max_seconds ⇒ Object (readonly)
Maximum number of elapased seconds before external process is killed
54 55 56 |
# File 'lib/process_watcher/watcher.rb', line 54 def max_seconds @max_seconds end |
Instance Method Details
#launch_and_watch(cmd, args, dest_dir) ⇒ Object
Launch given command as external process and watch given directory so it doesn’t exceed given size. Also watch time elapsed and kill external process if either the size of the watched directory exceed Note: This method is not thread-safe, instantiate one watcher per thread
Parameters
- cmd(String)
-
command to run
- args(Array)
-
arguments for
cmd
- dest_dir(String)
-
Watched directory
Return
- res(RightScale::WatchStatus)
-
Outcome of watch, see RightScale::WatchStatus
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/process_watcher/watcher.rb', line 78 def launch_and_watch(cmd, args, dest_dir) exit_code = nil output = '' monitor = ProcessMonitor.new # Run external process and monitor it in a new thread, platform specific pid = monitor.spawn(cmd, *args) do |data| output << data[:output] if data[:output] exit_code = data[:exit_code] if data.include?(:exit_code) end # Loop until process is done or times out or takes too much space timed_out = repeat(1, @max_seconds) do if @max_bytes < 0 exit_code else size = 0 Find.find(dest_dir) { |f| size += File.stat(f).size rescue 0 if File.file?(f) } if File.directory?(dest_dir) size > @max_bytes || exit_code end end # Cleanup and report status # Note: We need to store the exit status before we kill the underlying process so that # if it finished in the mean time we still report -1 as exit code if exit_code exit_status = exit_code outcome = :success else exit_status = -1 outcome = (timed_out ? :timeout : :size_exceeded) Process.kill('INT', pid) end # Cleanup any open handle etc., platform specific monitor.cleanup res = WatchStatus.new(outcome, exit_status, output) end |