class GroongaQueryLog::Replayer

Public Class Methods

new(options) click to toggle source
# File lib/groonga-query-log/replayer.rb, line 26
def initialize(options)
  @options = options
  @queue = SizedQueue.new(@options.request_queue_size)
  @responses = Queue.new
end

Public Instance Methods

replay(input) click to toggle source
# File lib/groonga-query-log/replayer.rb, line 32
def replay(input)
  producer = run_producer(input)
  consumers = run_consumers
  response_logger = run_response_logger
  producer.join
  consumers.each(&:join)
  response_logger.join
end

Private Instance Methods

available_command?(command) click to toggle source
# File lib/groonga-query-log/replayer.rb, line 136
def available_command?(command)
  case command.command_name
  when "load"
    not command.values.nil?
  else
    true
  end
end
replay_command(client, id, command) click to toggle source
# File lib/groonga-query-log/replayer.rb, line 102
def replay_command(client, id, command)
  command["cache"] = "no" if @options.disable_cache?
  response = client.execute(command)
  case command.output_type
  when :json, :xml, :tsv
    response.raw << "\n" unless response.raw.end_with?("\n")
  end
  @responses.push(response)
end
run_consumer() click to toggle source
# File lib/groonga-query-log/replayer.rb, line 77
def run_consumer
  @options.create_client do |client|
    loop do
      id, statistic = @queue.pop
      if id.nil?
        @responses.push(nil)
        return true
      end
      begin
        replay_command(client, id, statistic.command)
      rescue => error
        # TODO: add error log mechanism
        $stderr.puts(Time.now.iso8601(6))
        $stderr.puts(statistic.command.original_source)
        if error.respond_to?(:raw_error)
          error = raw_error
        end
        $stderr.puts(error.message)
        $stderr.puts(error.backtrace)
        return false
      end
    end
  end
end
run_consumers() click to toggle source
# File lib/groonga-query-log/replayer.rb, line 67
def run_consumers
  @options.n_clients.times.collect do
    Thread.new do
      loop do
        break if run_consumer
      end
    end
  end
end
run_producer(input) click to toggle source
# File lib/groonga-query-log/replayer.rb, line 42
def run_producer(input)
  Thread.new do
    parser = Parser.new
    id = 0
    @options.create_request_output do |output|
      parser.parse(input) do |statistic|
        next if statistic.command.nil?
        next unless target_command?(statistic.command)
        next unless available_command?(statistic.command)
        # TODO: validate orignal_source is one line
        output.puts(statistic.command.original_source)
        output.flush
        if @options.output_type
          statistic.command[:output_type] ||= @options.output_type
        end
        @queue.push([id, statistic])
        id += 1
      end
    end
    @options.n_clients.times do
      @queue.push(nil)
    end
  end
end
run_response_logger() click to toggle source
# File lib/groonga-query-log/replayer.rb, line 112
def run_response_logger
  Thread.new do
    @options.create_responses_output do |output|
      @options.create_responses_output do |error_output|
        loop do
          response = @responses.pop
          break if response.nil?
          # TODO: reorder by ID
          output.print(response.raw)
          output.flush
          unless response.success?
            error_output.print(response.raw)
            error_output.flush
          end
        end
      end
    end
  end
end
target_command?(command) click to toggle source
# File lib/groonga-query-log/replayer.rb, line 132
def target_command?(command)
  @options.target_command_name?(command.command_name)
end