class ABProf::ABHarnessProcess
Attributes
last_iters[R]
last_run[R]
Public Class Methods
new(command_line, opts = {})
click to toggle source
# File lib/abprof.rb, line 183 def initialize command_line, opts = {} debug "Controller of nobody yet: SPAWN" @in_reader, @in_writer = IO.pipe @out_reader, @out_writer = IO.pipe @in_writer.sync = true @out_writer.sync = true @debug = opts[:debug] @pid = fork do STDOUT.reopen(@out_writer) STDIN.reopen(@in_reader) @out_reader.close @in_writer.close ENV['ABDEBUG'] = @debug.inspect if command_line.respond_to?(:call) STDERR.puts "Caution! An ABProf Harness process (non-bare) is being used with a block. This is almost never what you want!" command_line.call elsif command_line.respond_to?(:to_s) exec command_line.to_s else raise "Don't know how to execute benchmark code: #{command_line.inspect}!" end exit! 0 end @out_writer.close @in_reader.close debug "Controller spawned #{@pid} (debug: #{@debug.inspect})" end
Public Instance Methods
debug(string)
click to toggle source
# File lib/abprof.rb, line 179 def debug string STDERR.puts(string) if @debug end
kill()
click to toggle source
# File lib/abprof.rb, line 220 def kill debug "Controller of #{@pid}: DIE" ::Process.detach @pid ::Process.kill "TERM", @pid end
quit()
click to toggle source
# File lib/abprof.rb, line 215 def quit debug "Controller of #{@pid}: QUIT" @in_writer.write "QUIT\n" end
run_iters(n)
click to toggle source
# File lib/abprof.rb, line 226 def run_iters(n) debug "Controller of #{@pid}: #{n} ITERS" @in_writer.write "ITERS #{n.to_i}\n" ignored_out = 0 state = :failed t_start = Time.now loop do # Read and block output = @out_reader.gets ignored_out += output.length debug "Controller of #{@pid} out: #{output.inspect}" if output =~ /^VALUES/ # These anchors match newlines, too state = :succeeded vals = MultiJson.load output[7..-1] raise "Must return an array value from iterations!" unless vals.is_a?(Array) raise "Must return an array of numbers from iterations!" unless vals[0].is_a?(Numeric) @last_run = vals break elsif output =~ /^VALUE/ # These anchors match newlines, too state = :succeeded val = output[6..-1].to_f raise "Must return a number from iterations!" unless val.is_a?(Numeric) @last_run = [ val ] break elsif output =~ /^OK$/ # These anchors match newlines, too state = :succeeded_get_time break elsif output =~ /^NOT OK$/ # These anchors match newlines, too # Failed, break state = :explicit_not_ok break elsif ignored_out > 10_000 # 10k of output and no OK? Bail with failed state. state = :too_much_output_without_status break end # None of these? Loop again. end t_end = Time.now unless [:succeeded, :succeeded_get_time].include?(state) self.kill STDERR.puts "Killing process #{@pid} after failed iterations, error code #{state.inspect}" end @last_run = [ (t_end - t_start).to_f ] if state == :succeeded_get_time @last_iters = n @last_run end