class Hoosegow::Protocol::Inmate

bin/hoosegow client (where the inmate code runs)

Translates stdin into a method call on on inmate. Encodes yields and the return value onto a stream.

Public Class Methods

new(options) click to toggle source

Options:

  • :stdout - real stdout, where we can write things that our parent process will see

  • :intercepted - where this process or child processes write STDOUT to

  • (optional) :inmate - the hoosegow instance to use as the inmate.

  • (optional) :stdin - where to read the encoded method call data.

# File lib/hoosegow/protocol.rb, line 78
def initialize(options)
  @inmate       = options.fetch(:inmate) { Hoosegow.new(:no_proxy => true) }
  @stdin        = options.fetch(:stdin, $stdin)
  @stdout       = options.fetch(:stdout)
  @intercepted  = options.fetch(:intercepted)
  @stdout_mutex = Mutex.new
end
run(options) click to toggle source
# File lib/hoosegow/protocol.rb, line 66
def self.run(options)
  o = new(options)
  o.intercepting do
    o.run
  end
end

Public Instance Methods

intercepting() { || ... } click to toggle source
# File lib/hoosegow/protocol.rb, line 97
def intercepting
  start_intercepting
  yield
ensure
  stop_intercepting
end
run() click to toggle source
# File lib/hoosegow/protocol.rb, line 86
def run
  name, args = MessagePack::Unpacker.new(@stdin).read
  result = @inmate.send(name, *args) do |*yielded|
    report(:yield, yielded)
    nil # Don't return anything from the inmate's `yield`.
  end
  report(:return, result)
rescue => e
  report(:raise, {:class => e.class.name, :message => e.message, :backtrace => e.backtrace})
end
start_intercepting() click to toggle source
# File lib/hoosegow/protocol.rb, line 104
def start_intercepting
  @intercepting = true
  @intercept_thread = Thread.new do
    begin
      loop do
        if IO.select([@intercepted], nil, nil, 0.1)
          report(:stdout, @intercepted.read_nonblock(100000))
        elsif ! @intercepting
          break
        end
      end
    rescue EOFError
      # stdout is closed, so we can stop checking it.
    end
  end
end
stop_intercepting() click to toggle source
# File lib/hoosegow/protocol.rb, line 121
def stop_intercepting
  @intercepting = false
  @intercept_thread.join
end

Private Instance Methods

report(type, data) click to toggle source
# File lib/hoosegow/protocol.rb, line 128
def report(type, data)
  @stdout_mutex.synchronize { @stdout.write(MessagePack.pack([type, data])) }
end