class ABProf::ABWorker

This class is used by programs that are being profiled. It’s necessarily a singleton since it needs to control STDIN. The bare mode can do without it, but it’s needed for harness processes.

Public Class Methods

debug(string) click to toggle source
# File lib/abprof.rb, line 25
def self.debug string
  STDERR.puts(string) if ENV['ABDEBUG'] == "true"
end
iteration(&block) click to toggle source
# File lib/abprof.rb, line 29
def self.iteration(&block)
  @iter_block = block
  @return = :none
end
iteration_with_return_value(&block) click to toggle source
# File lib/abprof.rb, line 34
def self.iteration_with_return_value(&block)
  @iter_block = block
  @return = :per_iteration
end
n_iterations_with_return_value(&block) click to toggle source
# File lib/abprof.rb, line 39
def self.n_iterations_with_return_value(&block)
  @iter_block = block
  @return = :per_n_iterations
end
read_once() click to toggle source
# File lib/abprof.rb, line 72
def self.read_once
  debug "WORKER #{Process.pid}: read loop"
  @input ||= ""
  @input += (STDIN.gets || "")
  debug "WORKER #{Process.pid}: Input #{@input.inspect}"
  if @input["\n"]
    command, @input = @input.split("\n", 2)
    debug "WORKER #{Process.pid}: command: #{command.inspect}"
    if command == "QUIT"
      exit 0
    elsif command["ITERS"]
      iters = command[5..-1].to_i
      values = run_n iters
      STDOUT.flush  # Why does this synchronous file descriptor not flush when given a string with a newline? Ugh!
      debug "WORKER #{Process.pid}: finished command ITERS: OK"
    else
      STDERR.puts "Unrecognized ABProf command: #{command.inspect}!"
      exit -1
    end
  end
end
run_n(n) click to toggle source
# File lib/abprof.rb, line 44
def self.run_n(n)
  debug "WORKER #{Process.pid}: running #{n} times [#{@return.inspect}]"

  case @return
  when :none
    n.times do
      @iter_block.call
    end
    STDOUT.write "OK\n"
  when :per_iteration
    values = (0..(n-1)).map { |i| @iter_block.call.to_f }
    STDOUT.write "VALUES #{values.inspect}\n"
  when :per_n_iterations
    value = @iter_block.call(n)
    if value.respond_to?(:each)
      # Return array of numbers
      debug "WORKER #{Process.pid}: Sent to controller: VALUES #{value.to_a.inspect}"
      STDOUT.write "VALUES #{value.to_a.inspect}\n"
    else
      # Return single number
      debug "WORKER #{Process.pid}: Sent to controller: VALUE #{value.to_f}"
      STDOUT.write "VALUE #{value.to_f}\n"
    end
  else
    raise "Unknown @return value #{@return.inspect} inside abprof!"
  end
end
start() click to toggle source
# File lib/abprof.rb, line 94
def self.start
  loop do
    read_once
  end
end

Public Instance Methods

debug(string) click to toggle source
# File lib/abprof.rb, line 22
def debug string
  STDERR.puts(string) if ENV['ABDEBUG'] == "true"
end