Class: Adhearsion::Initializer

Inherits:
Object
  • Object
show all
Defined in:
lib/adhearsion/initializer.rb,
lib/adhearsion/initializer/drb.rb,
lib/adhearsion/initializer/ldap.rb,
lib/adhearsion/initializer/xmpp.rb,
lib/adhearsion/initializer/rails.rb,
lib/adhearsion/initializer/asterisk.rb,
lib/adhearsion/initializer/database.rb

Defined Under Namespace

Classes: AsteriskInitializer, DatabaseInitializer, DrbInitializer, InitializationFailedError, LdapInitializer, RailsInitializer, XMPPInitializer

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path = nil, options = {}) ⇒ Initializer

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".


125
126
127
128
129
130
131
132
# File 'lib/adhearsion/initializer.rb', line 125

def initialize(path=nil, options={})
  @@started = true
  @path     = path
  @daemon   = options[:daemon] || ENV['DAEMON']
  @pid_file = options[:pid_file].nil? ? ENV['PID_FILE'] : options[:pid_file]
  @loaded_init_files  = options[:loaded_init_files]
  self.class.ahn_root = path
end

Instance Attribute Details

#ahn_app_log_directoryObject (readonly)

Returns the value of attribute ahn_app_log_directory.



112
113
114
# File 'lib/adhearsion/initializer.rb', line 112

def ahn_app_log_directory
  @ahn_app_log_directory
end

#daemonObject (readonly)

Returns the value of attribute daemon.



112
113
114
# File 'lib/adhearsion/initializer.rb', line 112

def daemon
  @daemon
end

#log_fileObject (readonly)

Returns the value of attribute log_file.



112
113
114
# File 'lib/adhearsion/initializer.rb', line 112

def log_file
  @log_file
end

#pathObject (readonly)

Returns the value of attribute path.



112
113
114
# File 'lib/adhearsion/initializer.rb', line 112

def path
  @path
end

#pid_fileObject (readonly)

Returns the value of attribute pid_file.



112
113
114
# File 'lib/adhearsion/initializer.rb', line 112

def pid_file
  @pid_file
end

Class Method Details

.ahn_root=(path) ⇒ Object



93
94
95
96
97
98
99
# File 'lib/adhearsion/initializer.rb', line 93

def ahn_root=(path)
  if Object.constants.include?("AHN_ROOT")
    Object.const_get(:AHN_ROOT).base_path = File.expand_path(path)
  else
    Object.const_set(:AHN_ROOT, PathString.new(File.expand_path(path)))
  end
end

.get_rules_from(location) ⇒ Object



88
89
90
91
# File 'lib/adhearsion/initializer.rb', line 88

def get_rules_from(location)
  location = File.join location, ".ahnrc" if File.directory? location
  File.exists?(location) ? YAML.load_file(location) : nil
end

.start(*args, &block) ⇒ Object



101
102
103
# File 'lib/adhearsion/initializer.rb', line 101

def start(*args, &block)
  new(*args, &block).start
end

.start_from_init_file(file, ahn_app_path) ⇒ Object



105
106
107
108
# File 'lib/adhearsion/initializer.rb', line 105

def start_from_init_file(file, ahn_app_path)
  return if defined?(@@started) && @@started
  start ahn_app_path, :loaded_init_files => file
end

Instance Method Details

#bootstrap_rcObject

This step in the initialization process loads the .ahnrc in the given app folder. With the information in .ahnrc, we can continue the initialization knowing where certain files are specifically.



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# File 'lib/adhearsion/initializer.rb', line 196

def bootstrap_rc
  rules = self.class.get_rules_from AHN_ROOT

  AHN_CONFIG.ahnrc = rules

  # DEPRECATION: Check if the old paths format is being used. If so, abort and notify.
  if rules.has_key?("paths") && rules["paths"].kind_of?(Hash)
    paths = rules["paths"].each_pair do |key,value|
      if value.kind_of?(Hash)
        if value.has_key?("directory") || value.has_key?("pattern")
          puts
          puts *caller
          puts

          abort <<-WARNING
Deprecation Warning
-------------------
The (hidden) .ahnrc file in this app is of an older format and needs to be fixed.

There is a rake task to automatically fix it or you can do it manually. Note: it's
best if you do it manually so you can retain the YAML comments in your .ahnrc file.

The rake task is called "deprecations:fix_ahnrc_path_format".

To do it manually, find all entries in the "paths" section of your ".ahnrc" file
which look like the following:

paths:
  key_name_could_be_anything:
directory: some_folder
pattern: *.rb

Note: the "models" section had this syntax before:

models:
  directory: models
  pattern: "*.rb"

The NEW syntax is as follows (using models as an example):

models: models/*.rb

This new format is much cleaner.

Adhearsion will abort until you fix this. Sorry for the incovenience.
          WARNING
        end
      end
    end
  end

  gems = rules['gems']
  if gems.kind_of?(Hash) && gems.any? && respond_to?(:gem)
    gems.each_pair do |gem_name,properties_hash|
      if properties_hash && properties_hash["version"]
        gem gem_name, properties_hash["version"]
      else
        gem gem_name
      end
      if properties_hash
        case properties_hash["require"]
          when Array
            properties_hash["require"].each { |lib| require lib }
          when String
            require properties_hash["require"]
        end
      end
    end
  end
end

#catch_termination_signalObject



184
185
186
187
188
189
190
# File 'lib/adhearsion/initializer.rb', line 184

def catch_termination_signal
  %w'INT TERM'.each do |process_signal|
    trap process_signal do
      Adhearsion.shutdown!
    end
  end
end

#create_pid_fileObject



339
340
341
342
343
344
345
346
347
348
349
# File 'lib/adhearsion/initializer.rb', line 339

def create_pid_file
  if pid_file
    File.open pid_file, 'w' do |file|
      file.puts Process.pid
    end

    Events.register_callback :shutdown do
      File.delete(pid_file) if File.exists?(pid_file)
    end
  end
end

#daemonize!Object



321
322
323
324
325
# File 'lib/adhearsion/initializer.rb', line 321

def daemonize!
  ahn_log "Daemonizing now! Creating #{pid_file}."
  extend Adhearsion::CustomDaemonizer
  daemonize log_file
end

#default_pid_pathObject



162
163
164
# File 'lib/adhearsion/initializer.rb', line 162

def default_pid_path
  File.join AHN_ROOT, 'adhearsion.pid'
end

#init_components_subsystemObject



351
352
353
354
355
356
357
358
359
360
361
# File 'lib/adhearsion/initializer.rb', line 351

def init_components_subsystem
  @components_directory = File.expand_path "components"
  if File.directory? @components_directory
    Components.component_manager = Components::ComponentManager.new @components_directory
    Kernel.send(:const_set, :COMPONENTS, Components.component_manager.lazy_config_loader)
    Components.component_manager.globalize_global_scope!
    Components.component_manager.extend_object_with(Theatre::CallbackDefinitionLoader, :events)
  else
    ahn_log.warn "No components directory found. Not initializing any components."
  end
end

#init_datasourcesObject



273
274
275
276
277
278
279
# File 'lib/adhearsion/initializer.rb', line 273

def init_datasources
  require 'adhearsion/initializer/database.rb'
  require 'adhearsion/initializer/ldap.rb'

  DatabaseInitializer.start   if AHN_CONFIG.database_enabled?
  LdapInitializer.start       if AHN_CONFIG.ldap_enabled?
end

#init_events_fileObject



310
311
312
313
314
315
# File 'lib/adhearsion/initializer.rb', line 310

def init_events_file
  application_events_files = AHN_CONFIG.files_from_setting("paths", "events")
  application_events_files.each do |file|
    Events.framework_theatre.load_events_file file
  end
end

#init_events_subsystemObject



297
298
299
300
301
302
303
304
305
306
307
308
# File 'lib/adhearsion/initializer.rb', line 297

def init_events_subsystem
  application_events_files = AHN_CONFIG.files_from_setting("paths", "events")
  if application_events_files.any?
    Events.register_callback(:shutdown) do
      ahn_log.events "Performing a graceful stop of events subsystem"
      Events.framework_theatre.graceful_stop!
    end
    Events.framework_theatre.start!
  else
    ahn_log.events.warn 'No entries in the "events" section of .ahnrc. Skipping its initialization.'
  end
end

#init_modulesObject



281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/adhearsion/initializer.rb', line 281

def init_modules

  require 'adhearsion/initializer/asterisk.rb'
  require 'adhearsion/initializer/drb.rb'
  require 'adhearsion/initializer/rails.rb'
  require 'adhearsion/initializer/xmpp.rb'
  # require 'adhearsion/initializer/freeswitch.rb'

  AsteriskInitializer.start   if AHN_CONFIG.asterisk_enabled?
  DrbInitializer.start        if AHN_CONFIG.drb_enabled?
  RailsInitializer.start      if AHN_CONFIG.rails_enabled?
  XMPPInitializer.start       if AHN_CONFIG.xmpp_enabled?
  # FreeswitchInitializer.start if AHN_CONFIG.freeswitch_enabled?

end

#initialize_log_fileObject



327
328
329
330
331
332
333
334
335
336
337
# File 'lib/adhearsion/initializer.rb', line 327

def initialize_log_file
  Dir.mkdir(ahn_app_log_directory) unless File.directory? ahn_app_log_directory
  file_logger = Log4r::FileOutputter.new("Main Adhearsion log file", :filename => log_file, :trunc => false)

  if should_daemonize?
    Logging::AdhearsionLogger.outputters  = file_logger
  else
    Logging::AdhearsionLogger.outputters << file_logger
  end
  Logging::DefaultAdhearsionLogger.redefine_outputters
end

#join_important_threadsObject

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



377
378
379
380
381
382
383
384
385
386
387
388
389
390
# File 'lib/adhearsion/initializer.rb', line 377

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 == IMPORTANT_THREADS.size
    begin
      IMPORTANT_THREADS[index].join
    rescue => e
      ahn_log.error "Error after join()ing Thread #{thread.inspect}. #{e.message}"
    ensure
      index = index + 1
    end
  end
end

#load_all_init_filesObject



267
268
269
270
271
# File 'lib/adhearsion/initializer.rb', line 267

def load_all_init_files
  init_files_from_rc = AHN_CONFIG.files_from_setting("paths", "init").map { |file| File.expand_path(file) }
  already_loaded_init_files = Array(@loaded_init_files).map { |file| File.expand_path(file) }
  (init_files_from_rc - already_loaded_init_files).each { |init| load init }
end

#load_componentsObject



363
364
365
366
367
# File 'lib/adhearsion/initializer.rb', line 363

def load_components
  if Components.component_manager
    Components.component_manager.load_components
  end
end

#resolve_log_file_pathObject



175
176
177
178
# File 'lib/adhearsion/initializer.rb', line 175

def resolve_log_file_path
  @ahn_app_log_directory = AHN_ROOT + '/log'
  @log_file = File.expand_path(ahn_app_log_directory + "/adhearsion.log")
end

#resolve_pid_file_pathObject



166
167
168
169
170
171
172
173
# File 'lib/adhearsion/initializer.rb', line 166

def resolve_pid_file_path
  @pid_file = if pid_file.equal?(true) then default_pid_path
  elsif pid_file then pid_file
  elsif pid_file.equal?(false) then nil
  # FIXME @pid_file = @daemon? Assignment or equality? I'm assuming equality.
  else @pid_file = @daemon ? default_pid_path : nil
  end
end

#should_daemonize?Boolean

Returns:

  • (Boolean)


317
318
319
# File 'lib/adhearsion/initializer.rb', line 317

def should_daemonize?
  @daemon
end

#startObject



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/adhearsion/initializer.rb', line 134

def start
  Adhearsion.status = :starting

  resolve_pid_file_path
  resolve_log_file_path
  daemonize! if should_daemonize?
  switch_to_root_directory
  catch_termination_signal
  create_pid_file if pid_file
  bootstrap_rc
  initialize_log_file
  load_all_init_files
  init_datasources
  init_components_subsystem
  init_modules
  init_events_subsystem
  load_components
  init_events_file

  ahn_log "Adhearsion v#{Adhearsion::VERSION::STRING} initialized!"
  Adhearsion.status = :running

  trigger_after_initialized_hooks
  join_important_threads

  self
end

#switch_to_root_directoryObject



180
181
182
# File 'lib/adhearsion/initializer.rb', line 180

def switch_to_root_directory
  Dir.chdir AHN_ROOT
end

#trigger_after_initialized_hooksObject



369
370
371
# File 'lib/adhearsion/initializer.rb', line 369

def trigger_after_initialized_hooks
  Events.trigger_immediately :after_initialized
end