Module: TestLab::Support::Parallel
- Included in:
- TestLab
- Defined in:
- lib/testlab/support/parallel.rb
Instance Method Summary collapse
-
#before_fork(pid) ⇒ Object
Our before fork hook; we should reset our SSH connections before forking, they will automatically re-establish after forking.
-
#do_parallel_actions(klass, objects, action, reverse = false, &block) ⇒ Boolean
Perform actions against a collection of objects in parallel.
-
#reset_screen ⇒ Boolean
Clear the screen and move the cursor to x:0, y:0 using ANSI escape codes.
Instance Method Details
#before_fork(pid) ⇒ Object
Our before fork hook; we should reset our SSH connections before forking, they will automatically re-establish after forking.
13 14 15 16 17 |
# File 'lib/testlab/support/parallel.rb', line 13 def before_fork(pid) defined?(nodes) and nodes.each do |node| node.ssh_shutdown! end end |
#do_parallel_actions(klass, objects, action, reverse = false, &block) ⇒ Boolean
Perform actions against a collection of objects in parallel.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/testlab/support/parallel.rb', line 9 def do_parallel_actions(klass, objects, action, reverse=false, &block) # Our before fork hook; we should reset our SSH connections before # forking, they will automatically re-establish after forking. def before_fork(pid) defined?(nodes) and nodes.each do |node| node.ssh_shutdown! end end # Clear the screen and move the cursor to x:0, y:0 using ANSI escape # codes # # @return [Boolean] Returns True if successful. def reset_screen self.ui.stdout.puts(ZTK::ANSI.reset) self.ui.stdout.puts(ZTK::ANSI.goto(0, 0)) true end klass_name = klass.to_s.split('::').last command = ZTK::Command.new(:silence => true, :ignore_exit_status => true) parallel = ZTK::Parallel.new(:ui => self.ui, :raise_exceptions => false) parallel.config do |config| config.before_fork = method(:before_fork) end priority_groups = klass.priority_groups (reverse == true) and priority_groups.reverse! priority_groups.each do |priority_group| selected_objects = objects.select{ |c| c.priority == priority_group } if selected_objects.count == 1 object = selected_objects.first block.call(object, action, klass) else selected_objects.each do |object| parallel.process do $0 = "TestLab #{klass_name.capitalize} #{action.to_s.capitalize}: #{object.id.inspect}" # Redirect all standard I/O to /dev/null self.ui.stdout.reopen("/dev/null", "a") self.ui.stderr.reopen("/dev/null", "a") self.ui.stdin.reopen("/dev/null") # Redirect logging to an object specific log file log_filename = "/tmp/testlab.log.#{object.id.to_s.downcase}" File.exists?(log_filename) && FileUtils.rm_f(log_filename) self.ui.logger = ZTK::Logger.new(log_filename) block.call(object, action, klass) end end while (parallel.count > 0) do = ("Parallel #{action.to_s.capitalize} Running:".yellow) reset_screen self.ui.stdout.puts() self.ui.stdout.puts("-" * .uncolor.length) self.ui.stdout.print(command.exec(%(ps u --pid #{parallel.pids.join(' ')} 2>/dev/null)).output) sleep(1) # Attempt to reap processes faster, otherwise we'll only reap one # per second if we're lucky. for x in 1..(parallel.count) do parallel.wait(Process::WNOHANG) end end reset_screen end end exception_count = parallel.results.count{ |result| (Exception === result) } if (exception_count > 0) = "Encountered #{exception_count} exceptions during parallel operations! (See logs for details)" self.ui.logger.fatal { } raise TestLabError, end true end |
#reset_screen ⇒ Boolean
Clear the screen and move the cursor to x:0, y:0 using ANSI escape codes
23 24 25 26 27 28 |
# File 'lib/testlab/support/parallel.rb', line 23 def reset_screen self.ui.stdout.puts(ZTK::ANSI.reset) self.ui.stdout.puts(ZTK::ANSI.goto(0, 0)) true end |