Module: ParallelCucumber::Helper::Processes
- Defined in:
- lib/parallel_cucumber/helper/processes.rb
Class Method Summary collapse
- .all_pids_dead?(root, logger, tree = nil, old_tree = nil) ⇒ Boolean
- .cp_rv(source, dest, logger = nil) ⇒ Object
-
.descendants(pid, logger, tree = nil, old_tree = nil, why = '-', level = 0) {|pid, old_tree_node| ... } ⇒ Object
Walks old_tree, and yields all processes (alive or dead) that match the pid, start time, and command in the new tree.
- .kill_tree(sig, root, logger, tree = nil, old_tree = nil) ⇒ Object
- .ms_windows? ⇒ Boolean
- .ps_tree ⇒ Object
Class Method Details
.all_pids_dead?(root, logger, tree = nil, old_tree = nil) ⇒ Boolean
54 55 56 57 58 |
# File 'lib/parallel_cucumber/helper/processes.rb', line 54 def all_pids_dead?(root, logger, tree = nil, old_tree = nil) # Note: returns from THIS function as well as descendants: short-circuit evaluation if any descendants remain. descendants(root, logger, tree, old_tree, 'dead?') { return false } true end |
.cp_rv(source, dest, logger = nil) ⇒ Object
9 10 11 12 13 14 15 16 17 |
# File 'lib/parallel_cucumber/helper/processes.rb', line 9 def cp_rv(source, dest, logger = nil) cp_out = if ms_windows? %x(powershell cp #{source} #{dest} -recurse -force 2>&1) else # Use system cp -r because Ruby's has crap diagnostics in weird situations. %x(cp -Rv #{source} #{dest} 2>&1) end logger.debug("Copy of #{source} to #{dest} said: #{cp_out}") if logger end |
.descendants(pid, logger, tree = nil, old_tree = nil, why = '-', level = 0) {|pid, old_tree_node| ... } ⇒ Object
Walks old_tree, and yields all processes (alive or dead) that match the pid, start time, and command in the new tree. Note that this will fumble children created since old_tree was created, but this thing is riddled with race conditions anyway.
63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/parallel_cucumber/helper/processes.rb', line 63 def descendants(pid, logger, tree = nil, old_tree = nil, why = '-', # rubocop:disable Metrics/ParameterLists level = 0, &block) tree ||= ps_tree old_tree ||= tree old_tree_node = old_tree[pid] unless old_tree_node logger.warn "== old tree node went missing - #{why} - skipping subtree level=#{level}: #{pid}" return end old_tree_node.fetch(:children, []).each { |c| descendants(c, logger, tree, old_tree, why, level + 1, &block) } yield(pid, old_tree_node) if tree[pid] && (tree[pid][:signature] == old_tree_node[:signature]) end |
.kill_tree(sig, root, logger, tree = nil, old_tree = nil) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/parallel_cucumber/helper/processes.rb', line 32 def kill_tree(sig, root, logger, tree = nil, old_tree = nil) if ms_windows? system("taskkill /pid #{root} /T") else descendants(root, logger, tree, old_tree, 'kill') do |pid, node| begin logger.warn "Sending signal #{sig} to #{node}" Process.kill(sig, pid.to_i) rescue Errno::ESRCH nil # It's gone already? Hurrah! end end end # Let's kill pid unconditionally: descendants will go astray once reparented. begin logger.warn "Sending signal #{sig} to root process #{root} just in case" Process.kill(sig, root.to_i) rescue Errno::ESRCH nil # It's gone already? Hurrah! end end |
.ms_windows? ⇒ Boolean
5 6 7 |
# File 'lib/parallel_cucumber/helper/processes.rb', line 5 def ms_windows? RUBY_PLATFORM =~ /mswin|mingw|migw32|cygwin/ end |
.ps_tree ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/parallel_cucumber/helper/processes.rb', line 19 def ps_tree if ms_windows? system('powershell scripts/process_tree.ps1') else %x(ps -ax -o ppid= -o pid= -o lstart= -o command=) .each_line.map { |l| l.strip.split(/ +/, 3) }.to_a .each_with_object({}) do |(ppid, pid, signature), tree| (tree[pid] ||= { children: [] })[:signature] = signature (tree[ppid] ||= { children: [] })[:children] << pid end end end |