Class/Module Index [+]

Quicksearch

PhusionPassenger::Utils

Utility functions.

Constants

FileSystemWatcher

Public Class Methods

included(klass) click to toggle source
# File lib/phusion_passenger/utils.rb, line 30
def self.included(klass)
  # When included into another class, make sure that Utils
  # methods are made private.
  public_instance_methods(false).each do |method_name|
    klass.send(:private, method_name)
  end
end
mktmpdir(prefix_suffix=nil, tmpdir=nil) click to toggle source

Like Dir.mktmpdir, but creates shorter filenames.

# File lib/phusion_passenger/utils/tmpio.rb, line 45
def self.mktmpdir(prefix_suffix=nil, tmpdir=nil)
  case prefix_suffix
  when nil
    prefix = "d"
    suffix = ""
  when String
    prefix = prefix_suffix
    suffix = ""
  when Array
    prefix = prefix_suffix[0]
    suffix = prefix_suffix[1]
  else
    raise ArgumentError, "unexpected prefix_suffix: #{prefix_suffix.inspect}"
  end
  tmpdir ||= Dir.tmpdir
  begin
    path = "#{tmpdir}/#{prefix}#{rand(0x100000000).to_s(36)}"
    path << suffix
    Dir.mkdir(path, 0700)
  rescue Errno::EEXIST
    retry
  end

  if block_given?
    begin
      yield path
    ensure
      FileUtils.remove_entry_secure path
    end
  else
    path
  end
end
new(filenames, termination_pipe = nil) click to toggle source
# File lib/phusion_passenger/utils/file_system_watcher.rb, line 60
def self.new(filenames, termination_pipe = nil)
  # Default parameter values, type conversion and exception
  # handling in C is too much of a pain.
  filenames = filenames.map do |filename|
    filename.to_s
  end
  return _new(filenames, termination_pipe)
end
opens_files?() click to toggle source
# File lib/phusion_passenger/utils/file_system_watcher.rb, line 69
def self.opens_files?
  return true
end

Public Instance Methods

connect_to_server(address) click to toggle source
# File lib/phusion_passenger/utils.rb, line 130
def connect_to_server(address)
  case get_socket_address_type(address)
  when :unix
    return UNIXSocket.new(address.sub(/^unix:/, ''))
  when :tcp
    host, port = address.sub(%{^tcp://}, '').split(':', 2)
    port = port.to_i
    return TCPSocket.new(host, port)
  else
    raise ArgumentError, "Unknown socket address type for '#{address}'."
  end
end
create_thread_and_abort_on_exception(*args) click to toggle source

A wrapper around Thread.new that installs a default exception handler. If an uncaught exception is encountered, it will immediately log the exception and abort the entire program.

Thread#abort_on_exception is also supposed to do that, but the problem is that it is implemented by forwarding the uncaught exception to the main thread, which may not expect that particular exception and may not handle it properly. The exception could be forwarded to the main thread during any point of the main thread's execution.

This method requires 'thread' and 'ruby_core_enhancements'. If 'debug_logging' is loaded and included in the current module, it will use that for logging.

# File lib/phusion_passenger/utils.rb, line 106
def create_thread_and_abort_on_exception(*args)
  Thread.new do
    Thread.current.abort_on_exception = true
    begin
      yield(*args)
    rescue SystemExit
      raise
    rescue Exception => e
      print_exception(nil, e)
      exit(1)
    end
  end
end
generate_random_id(method) click to toggle source

Generate a long, cryptographically secure random ID string, which is also a valid filename.

# File lib/phusion_passenger/utils.rb, line 40
def generate_random_id(method)
  data = File.open("/dev/urandom", "rb") do |f|
    f.read(64)
  end
  case method
  when :base64
    data = [data].pack('m')
    data.gsub!("\n", '')
    data.gsub!("+", '')
    data.gsub!("/", '')
    data.gsub!(/==$/, '')
    return data
  when :hex
    return data.unpack('H*')[0]
  else
    raise ArgumentError, "Invalid method #{method.inspect}"
  end
end
get_socket_address_type(address) click to toggle source
# File lib/phusion_passenger/utils.rb, line 120
def get_socket_address_type(address)
  if address =~ %{^unix:.}
    return :unix
  elsif address =~ %{^tcp://.}
    return :tcp
  else
    return :unknown
  end
end
global_backtrace_report() click to toggle source

Returns a string which reports the backtraces for all threads, or if that's not supported the backtrace for the current thread.

# File lib/phusion_passenger/utils.rb, line 183
def global_backtrace_report
  if Kernel.respond_to?(:caller_for_all_threads)
    all_thread_stacks = caller_for_all_threads
  elsif Thread.respond_to?(:list) && Thread.public_method_defined?(:backtrace)
    all_thread_stacks = {}
    Thread.list.each do |thread|
      all_thread_stacks[thread] = thread.backtrace
    end
  end

  output = "========== Process #{Process.pid}: backtrace dump ==========\n"
  if all_thread_stacks
    all_thread_stacks.each_pair do |thread, stack|
      if thread_name = thread[:name]
        thread_name = "(#{thread_name})"
      end
      stack ||= ["(empty)"]
      output << ("-" * 60) << "\n"
      output << "# Thread: #{thread.inspect}#{thread_name}, "
      if thread == Thread.main
        output << "[main thread], "
      end
      if thread == Thread.current
        output << "[current thread], "
      end
      output << "alive = #{thread.alive?}\n"
      output << ("-" * 60) << "\n"
      output << "    " << stack.join("\n    ")
      output << "\n\n"
    end
  else
    output << ("-" * 60) << "\n"
    output << "# Current thread: #{Thread.current.inspect}\n"
    output << ("-" * 60) << "\n"
    output << "    " << caller.join("\n    ")
  end
  return output
end
install_options_as_ivars(object, options, *keys) click to toggle source
# File lib/phusion_passenger/utils.rb, line 175
def install_options_as_ivars(object, options, *keys)
  keys.each do |key|
    object.instance_variable_set("@#{key}", options[key])
  end
end
local_socket_address?(address) click to toggle source
# File lib/phusion_passenger/utils.rb, line 143
def local_socket_address?(address)
  case get_socket_address_type(address)
  when :unix
    return true
  when :tcp
    host, port = address.sub(%{^tcp://}, '').split(':', 2)
    return host == "127.0.0.1" || host == "::1" || host == "localhost"
  else
    raise ArgumentError, "Unknown socket address type for '#{address}'."
  end
end
process_is_alive?(pid) click to toggle source

Checks whether the given process exists.

# File lib/phusion_passenger/utils.rb, line 156
def process_is_alive?(pid)
  begin
    Process.kill(0, pid)
    return true
  rescue Errno::ESRCH
    return false
  rescue SystemCallError => e
    return true
  end
end
require_option(hash, key) click to toggle source
# File lib/phusion_passenger/utils.rb, line 167
def require_option(hash, key)
  if hash.has_key?(key)
    return hash[key]
  else
    raise ArgumentError, "Option #{key.inspect} required"
  end
end
retry_at_most(n, *exceptions) click to toggle source
# File lib/phusion_passenger/utils.rb, line 59
def retry_at_most(n, *exceptions)
  n.times do |i|
    begin
      return yield
    rescue *exceptions
      if i == n - 1
        raise
      end
    end
  end
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.