Module: Zerg::Support::Process
- Defined in:
- lib/zerg_support/spawn.rb,
lib/zerg_support/spawn.rb,
lib/zerg_support/spawn.rb,
lib/zerg_support/process.rb
Overview
process management
Defined Under Namespace
Modules: Helpers
Constant Summary collapse
- @@no_multiple_pids =
false
Class Method Summary collapse
-
.kill(pid) ⇒ Object
Kills the process with the given pid.
-
.kill_primitive(pid, force = false) ⇒ Object
:nodoc: Wrapper around Process.kill that works on all platforms.
-
.kill_tree(root_pid) ⇒ Object
Kills all the processes descending from the process with the given pid.
-
.process_info(pid) ⇒ Object
Collects information about a single process.
-
.process_tree(*root_pids) ⇒ Object
Returns information about the descendants of the process with the given pid.
-
.processes(pids = nil) ⇒ Object
Collects information about processes with the given pids.
-
.processes_by_id(pids = nil) ⇒ Object
Collects information about processes with the given pids.
-
.spawn(binary, args = [], options = {}) ⇒ Object
Spawns a new process and returns its pid immediately.
-
.xlate_process_info(low_info) ⇒ Object
:nodoc:.
Class Method Details
.kill(pid) ⇒ Object
Kills the process with the given pid.
125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/zerg_support/process.rb', line 125 def self.kill(pid) begin self.kill_primitive pid, false Thread.new(pid) do |victim_pid| Kernel.sleep 0.2 self.kill_primitive(pid, true) rescue nil end rescue # we probably don't have the right to kill the process end end |
.kill_primitive(pid, force = false) ⇒ Object
:nodoc: Wrapper around Process.kill that works on all platforms.
114 115 116 |
# File 'lib/zerg_support/process.rb', line 114 def self.kill_primitive(pid, force = false) Process.kill(force ? 9 : 4, pid) end |
.kill_tree(root_pid) ⇒ Object
Kills all the processes descending from the process with the given pid.
138 139 140 141 142 |
# File 'lib/zerg_support/process.rb', line 138 def self.kill_tree(root_pid) self.process_tree(root_pid).each do |pinfo| self.kill pinfo[:pid] end end |
.process_info(pid) ⇒ Object
Collects information about a single process. Returns nil
56 57 58 59 |
# File 'lib/zerg_support/process.rb', line 56 def self.process_info(pid) pinfo = ps pid pinfo ? xlate_process_info(pinfo) : nil end |
.process_tree(*root_pids) ⇒ Object
Returns information about the descendants of the process with the given pid.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/zerg_support/process.rb', line 92 def self.process_tree(*root_pids) procs_by_ppid = {} proc_list = self.processes_by_id proc_list.each do |pid, pinfo| procs_by_ppid[pinfo[:parent_pid]] ||= [] procs_by_ppid[pinfo[:parent_pid]] << pinfo end proc_queue = root_pids.map { |pid| proc_list[pid] }.select { |pinfo| pinfo } index = 0 while index < proc_queue.length pid, index = proc_queue[index][:pid], index + 1 next unless procs_by_ppid.has_key? pid proc_queue += procs_by_ppid[pid] end return proc_queue end |
.processes(pids = nil) ⇒ Object
Collects information about processes with the given pids. Returns all processes if no list of pids is given.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/zerg_support/process.rb', line 63 def self.processes(pids = nil) if @@no_multiple_pids and !pids.empty pids.map { |pid| process_info pid } else begin if pids ps_result = ps(pids) else ps_result = ps end ps_result.map { |pinfo| xlate_process_info pinfo } rescue TypeError # we're using the real sys-proctable, and its ps doesn't like multiple # arguments @@no_multiple_pids = true processes pids end end end |
.processes_by_id(pids = nil) ⇒ Object
Collects information about processes with the given pids. The information is returned indexed by the processes’ pids.
85 86 87 88 89 |
# File 'lib/zerg_support/process.rb', line 85 def self.processes_by_id(pids = nil) retval = {} self.processes(pids).each { |pinfo| retval[pinfo[:pid]] = pinfo } return retval end |
.spawn(binary, args = [], options = {}) ⇒ Object
Spawns a new process and returns its pid immediately. Like Kernel.spawn in ruby1.9, except that the environment is passed as an option with the key :env
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 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/zerg_support/spawn.rb', line 80 def self.spawn(binary, args = [], = {}) # command line processing command_line = '"' + binary + '" "' + args.map { |a| a.gsub '"', '""' }.join('" "') + '"' # environment processing environment_string = nil if [:env] if [:unsetenv_others] environment = [:env] else environment = Hash.new.merge(ENV).merge([:env]) end environment_string = environment.keys.sort. map { |k| "#{k}=#{environment[k]}" }.join "\0" environment_string << "\0" end # redirection processing startup_info = {} files = {} stream_files = {} deferred_opens = [] [[STDIN, :stdin], [STDOUT, :stdout], [STDERR, :stderr]].each do |pair| next unless [pair.first] if [pair.first].kind_of? String filename = [pair.first] files[filename] ||= File.open(filename, (pair.last == :stdin) ? 'r' : 'w+') startup_info[pair.last] = files[filename] stream_files[pair.first] = files[filename] else deferred_opens << Kernel.proc do io = stream_files[[pair.first]] || pair.first startup_info[pair.last] = stream_files[pair.first] = io end end end deferred_opens.each { |d| d.call } # process leader creation_flags = 0 if [:pgroup] creation_flags |= Process::DETACHED_PROCESS if [:pgroup].kind_of? Numeric and [:pgroup] > 0 # TODO: what now? else creation_flags |= Process::CREATE_NEW_PROCESS_GROUP end end info = Process.create :command_line => command_line, :cwd => [:chdir] || Dir.pwd, :environment => environment_string, :creation_flags => creation_flags, :startup_info => startup_info files.each { |name, io| io.close } return info[:process_id] end |
.xlate_process_info(low_info) ⇒ Object
:nodoc:
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/zerg_support/process.rb', line 9 def self.xlate_process_info(low_info) { :pid => low_info.pid, :parent_pid => low_info.ppid, :real_uid => low_info.ruid || -1, :real_gid => low_info.rgid || -1, :start_time => low_info.start, :nice => low_info.nice || 0, :priority => low_info.priority || 0, :syscall_priority => low_info.user_priority || 0, :resident_size => (low_info.id_rss || 0) * 1024, :code_size => (low_info.ix_rss || 0) * 1024, :virtual_size => (low_info.is_rss || 0) * 1024, :percent_cpu => low_info.pctcpu, :percent_ram => low_info.pctmem, :state => low_info.state, :command_line => low_info.cmdline } end |