class Adhearsion::Initializer

Constants

DEFAULT_PID_FILE_NAME
InitializationFailedError

Attributes

daemon[R]
path[R]
pid_file[R]

Public Class Methods

new(options = {}) click to toggle source

Creation of pid_files

- You may want to have Adhearsion create a process identification
  file when it boots so that a crash monitoring program such as
  Monit can reboot if necessary or so the init script can kill it
  for system shutdowns.
- To have Adhearsion create a pid file in the default location (i.e.
  AHN_INSTALL_DIR/adhearsion.pid), supply :pid_file with 'true'. Otherwise
  one is not created UNLESS it is running in daemon mode, in which
  case one is created. You can force Adhearsion to not create one
  even in daemon mode by supplying "false".
# File lib/adhearsion/initializer.rb, line 31
def initialize(options = {})
  @@started = true
  @path     = path
  @mode     = options[:mode]
  @pid_file = options[:pid_file].nil? ? ENV['PID_FILE'] : options[:pid_file]
  @loaded_init_files  = options[:loaded_init_files]
  Adhearsion.root = '.'
end
start(*args, &block) click to toggle source
# File lib/adhearsion/initializer.rb, line 11
def start(*args, &block)
  new(*args, &block).start
end

Public Instance Methods

catch_termination_signal() click to toggle source
# File lib/adhearsion/initializer.rb, line 137
def catch_termination_signal
  self_read, self_write = IO.pipe

  %w(INT TERM HUP ALRM ABRT).each do |sig|
    trap sig do
      self_write.puts sig
    end
  end

  Thread.new do
    begin
      while readable_io = IO.select([self_read])
        signal = readable_io.first[0].gets.strip
        handle_signal signal
      end
    rescue => e
      logger.error "Crashed reading signals"
      logger.error e
      exit 1
    end
  end
end
configure_plugins() click to toggle source
# File lib/adhearsion/initializer.rb, line 245
def configure_plugins
  Plugin.configure_plugins
end
create_pid_file(pid = nil) click to toggle source
# File lib/adhearsion/initializer.rb, line 310
def create_pid_file(pid = nil)
  return unless pid_file

  logger.debug "Creating PID file #{pid_file}"

  File.open pid_file, 'w' do |file|
    file.puts pid || ::Process.pid
  end

  Events.register_callback :shutdown do
    File.delete(pid_file) if File.exists?(pid_file)
  end
end
daemonize!() click to toggle source
# File lib/adhearsion/initializer.rb, line 265
def daemonize!
  logger.info "Daemonizing now!"
  Adhearsion::CustomDaemonizer.daemonize resolve_log_file_path do |pid|
    create_pid_file pid
  end
end
debugging_items() click to toggle source
# File lib/adhearsion/initializer.rb, line 80
def debugging_items
  [
    "OS: #{RbConfig::CONFIG['host_os']} - RUBY: #{RUBY_ENGINE} #{RUBY_VERSION}",
    "Environment: #{ENV.inspect}",
    Adhearsion.config.description(:all),
    "Gem versions: #{Gem.loaded_specs.inject([]) { |c,g| c << "#{g[0]} #{g[1].version}" }}"
  ]
end
debugging_log() click to toggle source
# File lib/adhearsion/initializer.rb, line 89
def debugging_log
  debugging_items.each do |item|
    logger.trace item
  end
end
default_pid_path() click to toggle source
# File lib/adhearsion/initializer.rb, line 114
def default_pid_path
  File.join Adhearsion.config.root, DEFAULT_PID_FILE_NAME
end
handle_signal(signal) click to toggle source
# File lib/adhearsion/initializer.rb, line 160
def handle_signal(signal)
  case signal
  when 'INT', 'TERM'
    logger.info "Received SIG#{signal}. Shutting down."
    Adhearsion::Process.shutdown
  when 'HUP'
    logger.info "Received SIGHUP. Reopening logfiles."
    Adhearsion::Logging.reopen_logs
  when 'ALRM'
    logger.info "Received SIGALRM. Toggling trace logging."
    Adhearsion::Logging.toggle_trace!
  when 'ABRT'
    logger.info "Received ABRT signal. Forcing stop."
    Adhearsion::Process.force_stop
  end
end
init_get_logging_appenders() click to toggle source
# File lib/adhearsion/initializer.rb, line 211
def init_get_logging_appenders
  @file_loggers ||= memoize_logging_appenders
end
init_plugins() click to toggle source
# File lib/adhearsion/initializer.rb, line 249
def init_plugins
  Plugin.init_plugins
end
initialize_exception_logger() click to toggle source
# File lib/adhearsion/initializer.rb, line 304
def initialize_exception_logger
  Events.register_handler :exception do |e, l|
    (l || logger).error e
  end
end
initialize_log_paths() click to toggle source

Creates the relative paths associated to log files i.e.

  • log_file = “log/adhearsion.log” => creates 'log' folder

  • log_file = “log/test/adhearsion.log” => creates 'log' and 'log/test' folders

# File lib/adhearsion/initializer.rb, line 284
def initialize_log_paths
  outputters = Array(Adhearsion.config.platform.logging.outputters)
  outputters.select{|o| o.is_a?(String)}.each do |o|
    o = o.split("/")
    unless o[0].empty? # only if relative path
      o.pop # not consider filename
      o.inject("") do |path, folder|
        path = path.concat(folder).concat("/")
        Dir.mkdir(path) unless File.directory? path
        path
      end
    end
  end
end
join_important_threads() click to toggle source

This method will block Thread.main() until calling join() has returned for all Threads in Adhearsion::Process.important_threads. Note: important_threads won't always contain Thread instances. It simply requires the objects respond to join().

# File lib/adhearsion/initializer.rb, line 336
def join_important_threads
  # Note: we're using this ugly accumulator to ensure that all threads have ended since IMPORTANT_THREADS will almost
  # certainly change sizes after this method is called.
  index = 0
  until index == Adhearsion::Process.important_threads.size
    begin
      Adhearsion::Process.important_threads[index].join
    rescue => e
      logger.error "Error after joining Thread #{Thread.inspect}. #{e.message}"
    ensure
      index = index + 1
    end
  end
end
launch_console() click to toggle source
# File lib/adhearsion/initializer.rb, line 272
def launch_console
  Thread.new do
    catching_standard_errors do
      Adhearsion::Console.run
    end
  end
end
load_config_file() click to toggle source
# File lib/adhearsion/initializer.rb, line 197
def load_config_file
  load "#{Adhearsion.config.root}/config/adhearsion.rb"
end
load_events_file() click to toggle source
# File lib/adhearsion/initializer.rb, line 201
def load_events_file
  path = "#{Adhearsion.config.root}/config/events.rb"
  load path if File.exists?(path)
end
load_lib_folder() click to toggle source

Loads files in application lib folder @return [Boolean] if files have been loaded (lib folder is configured to not nil and actually exists)

# File lib/adhearsion/initializer.rb, line 180
def load_lib_folder
  return false if Adhearsion.config.platform.lib.nil?

  lib_folder = [Adhearsion.config.platform.root, Adhearsion.config.platform.lib].join '/'
  return false unless File.directory? lib_folder

  $LOAD_PATH.unshift lib_folder

  Dir.chdir lib_folder do
    rbfiles = File.join "**", "*.rb"
    Dir.glob(rbfiles).each do |file|
      require "#{lib_folder}/#{file}"
    end
  end
  true
end
load_routes_file() click to toggle source
# File lib/adhearsion/initializer.rb, line 206
def load_routes_file
  path = "#{Adhearsion.config.root}/config/routes.rb"
  load path if File.exists?(path)
end
memoize_logging_appenders() click to toggle source
# File lib/adhearsion/initializer.rb, line 215
def memoize_logging_appenders
  appenders = Array(Adhearsion.config.platform.logging.outputters.dup)
  # Any filename in the outputters array is mapped to a ::Logging::Appenders::File instance
  appenders.map! do |a|
    case a
    when String
      f = if a.start_with?("/")
        a
      else
        File.expand_path(Adhearsion.config.root.dup.concat("/").concat(a))
      end
      ::Logging.appenders.file(f,
        :layout => ::Logging.layouts.pattern(
          Adhearsion::Logging.adhearsion_pattern_options
        ),
       :auto_flushing => 2,
       :flush_period => 2
      )
    else
     a
    end
  end

  if should_daemonize?
    appenders
  else
    appenders += Adhearsion::Logging.default_appenders
  end
end
need_console?() click to toggle source
# File lib/adhearsion/initializer.rb, line 261
def need_console?
  @mode == :console
end
resolve_log_file_path() click to toggle source
# File lib/adhearsion/initializer.rb, line 130
def resolve_log_file_path
  _log_file = Adhearsion.config.platform.logging.outputters
  _log_file = _log_file[0] if _log_file.is_a?(Array)
  _log_file = File.expand_path(Adhearsion.config.root.dup.concat("/").concat(_log_file)) unless _log_file.start_with?("/")
  _log_file
end
resolve_pid_file_path() click to toggle source
# File lib/adhearsion/initializer.rb, line 118
def resolve_pid_file_path
  @pid_file = if pid_file.equal?(true)
    default_pid_path
  elsif pid_file.equal?(false)
    nil
  elsif pid_file
    File.expand_path pid_file
  else
    should_daemonize? ? default_pid_path : nil
  end
end
run_plugins() click to toggle source
# File lib/adhearsion/initializer.rb, line 253
def run_plugins
  Plugin.run_plugins
end
set_ahn_proc_name() click to toggle source
# File lib/adhearsion/initializer.rb, line 324
def set_ahn_proc_name
  Adhearsion::LinuxProcName.set_proc_name Adhearsion.config.platform.process_name
end
should_daemonize?() click to toggle source
# File lib/adhearsion/initializer.rb, line 257
def should_daemonize?
  @mode == :daemon
end
start() click to toggle source
# File lib/adhearsion/initializer.rb, line 40
def start
  catch :boot_aborted do
    resolve_pid_file_path
    configure_plugins
    load_lib_folder
    load_config_file
    load_events_file
    load_routes_file
    initialize_log_paths

    if should_daemonize?
      daemonize!
    else
      create_pid_file
    end

    Adhearsion.statistics
    start_logging
    debugging_log
    launch_console if need_console?
    catch_termination_signal
    set_ahn_proc_name
    initialize_exception_logger
    update_rails_env_var
    init_plugins

    run_plugins
    trigger_after_initialized_hooks

    Adhearsion::Process.booted if Adhearsion.status == :booting

    logger.info "Adhearsion v#{Adhearsion::VERSION} initialized in \"#{Adhearsion.config.platform.environment}\"!" if Adhearsion.status == :running
  end

  # This method will block until all important threads have finished.
  # When it does, the process will exit.
  join_important_threads
  self
end
start_logging() click to toggle source
# File lib/adhearsion/initializer.rb, line 299
def start_logging
  outputters = init_get_logging_appenders
  Adhearsion::Logging.start outputters, Adhearsion.config.platform.logging.level, Adhearsion.config.platform.logging.formatter
end
trigger_after_initialized_hooks() click to toggle source
# File lib/adhearsion/initializer.rb, line 328
def trigger_after_initialized_hooks
  Events.trigger_immediately :after_initialized
end
update_rails_env_var() click to toggle source
# File lib/adhearsion/initializer.rb, line 95
def update_rails_env_var
  env = ENV['AHN_ENV']
  if env && Adhearsion.config.valid_environment?(env.to_sym)
    unless ENV['RAILS_ENV']
      logger.info "Copying AHN_ENV (#{env}) to RAILS_ENV"
      ENV['RAILS_ENV'] = env
    end
  else
    unless ENV['RAILS_ENV']
      env = Adhearsion.config.platform.environment.to_s
      ENV['AHN_ENV'] = env
      logger.info "Setting RAILS_ENV to \"#{env}\""
      ENV['RAILS_ENV'] = env
    end
  end
  logger.warn "AHN_ENV(#{ENV['AHN_ENV']}) does not match RAILS_ENV(#{ENV['RAILS_ENV']})!" unless ENV['RAILS_ENV'] == ENV['AHN_ENV']
  env
end