class RubyAwaitNode::Runtime

Attributes

debug[RW]
nodejs_cmd[RW]
pid[RW]
port[RW]
semaphore[RW]

Public Class Methods

new(opts = {}) click to toggle source
# File lib/ruby-await-node/runtime.rb, line 9
def initialize(opts = {})
  srand

  @debug = opts[:debug]
  @nodejs_cmd = "node"
  @pid = nil
  @semaphore = Mutex.new
end

Public Instance Methods

available?() click to toggle source
# File lib/ruby-await-node/runtime.rb, line 22
def available?
  ENV["PATH"].split(":").detect do |path|
    %w{
      nodejs
      node
    }.detect do |node|
      File.exist?(File.join(path, node)) || File.symlink?(File.join(path, node))
    end
  end
end
context_class() click to toggle source
# File lib/ruby-await-node/runtime.rb, line 37
def context_class
  RubyAwaitNode::Context
end
deprecated?() click to toggle source
# File lib/ruby-await-node/runtime.rb, line 33
def deprecated?
  false
end
name() click to toggle source
# File lib/ruby-await-node/runtime.rb, line 18
def name
  "RubyAwaitNode"
end
provision_socket() click to toggle source

NOTE: this should be thread-safe

# File lib/ruby-await-node/runtime.rb, line 42
def provision_socket
  ensure_startup unless @pid

  wait_socket = nil
  checks = 0
  max_retries = 12

  while checks < max_retries
    begin
      checks += 1
      wait_socket = UNIXSocket.new(@port)
      break
    rescue Errno::ENOENT, Errno::ECONNREFUSED, Errno::ENOTDIR
      wait_socket = nil
      sleep 0.5
    end
  end

  if checks >= max_retries
    ensure_shutdown
    raise RuntimeError, "unable to connect to ruby-await-node.js server"
  end

  wait_socket
end

Private Instance Methods

ensure_shutdown() click to toggle source
# File lib/ruby-await-node/runtime.rb, line 94
def ensure_shutdown
  return unless @pid
  return unless Process.pid == @initialize_pid

  Process.kill("TERM", @pid) rescue Errno::ECHILD
  Process.wait(@pid) rescue Errno::ECHILD

  @port = nil
  @pid = nil
end
ensure_startup() click to toggle source
# File lib/ruby-await-node/runtime.rb, line 70
def ensure_startup
  @semaphore.synchronize {
    return if @pid

    @port = begin
      tmpfile = Tempfile.new("ruby-await-node")
      path = tmpfile.path
      tmpfile.close
      tmpfile.unlink
      path
    end

    ruby_await_node_js_path = File.join(File.dirname(File.expand_path(__FILE__)), '../../ruby-await-node.js')
    command_options = [ruby_await_node_js_path, "--debug #{!!@debug}"] # --other --command-line --options --go --here

    @initialize_pid = Process.pid
    @pid = Process.spawn({"PORT" => @port.to_s}, @nodejs_cmd, *command_options, {:err => :out})

    at_exit do
      ensure_shutdown
    end
  }
end