Class: Adhearsion::Initializer

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

Defined Under Namespace

Classes: AsteriskInitializer, DatabaseInitializer, DrbInitializer, InitializationFailedError, RailsInitializer

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


115
116
117
118
119
120
121
# File 'lib/adhearsion/initializer.rb', line 115

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

Instance Attribute Details

#ahn_app_log_directoryObject (readonly)

Returns the value of attribute ahn_app_log_directory.



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

def ahn_app_log_directory
  @ahn_app_log_directory
end

#daemonObject (readonly)

Returns the value of attribute daemon.



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

def daemon
  @daemon
end

#log_fileObject (readonly)

Returns the value of attribute log_file.



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

def log_file
  @log_file
end

#pathObject (readonly)

Returns the value of attribute path.



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

def path
  @path
end

#pid_fileObject (readonly)

Returns the value of attribute pid_file.



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

def pid_file
  @pid_file
end

Class Method Details

.ahn_root=(path) ⇒ Object



83
84
85
86
87
88
89
# File 'lib/adhearsion/initializer.rb', line 83

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



78
79
80
81
# File 'lib/adhearsion/initializer.rb', line 78

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



91
92
93
# File 'lib/adhearsion/initializer.rb', line 91

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

.start_from_init_file(file, ahn_app_path) ⇒ Object



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

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.



185
186
187
188
189
190
191
192
193
194
195
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
# File 'lib/adhearsion/initializer.rb', line 185

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



171
172
173
174
175
176
177
178
179
# File 'lib/adhearsion/initializer.rb', line 171

def catch_termination_signal
  %w'INT TERM'.each do |process_signal|
    trap process_signal do
      ahn_log "Shutting down gracefully at #{Time.now}."
      Events.trigger :shutdown
      exit
    end
  end
end

#create_pid_file(file = pid_file) ⇒ Object



318
319
320
321
322
323
324
325
326
327
328
# File 'lib/adhearsion/initializer.rb', line 318

def create_pid_file(file = pid_file)
  if 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



300
301
302
303
304
# File 'lib/adhearsion/initializer.rb', line 300

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

#default_pid_pathObject



149
150
151
# File 'lib/adhearsion/initializer.rb', line 149

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

#init_components_subsystemObject



330
331
332
333
334
335
336
337
338
339
340
# File 'lib/adhearsion/initializer.rb', line 330

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_events_fileObject



289
290
291
292
293
294
# File 'lib/adhearsion/initializer.rb', line 289

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



276
277
278
279
280
281
282
283
284
285
286
287
# File 'lib/adhearsion/initializer.rb', line 276

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



262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/adhearsion/initializer.rb', line 262

def init_modules
  require 'adhearsion/initializer/database.rb'
  require 'adhearsion/initializer/asterisk.rb'
  require 'adhearsion/initializer/drb.rb'
  require 'adhearsion/initializer/rails.rb'
  # require 'adhearsion/initializer/freeswitch.rb'
  
  DatabaseInitializer.start if AHN_CONFIG.database_enabled?
  AsteriskInitializer.start if AHN_CONFIG.asterisk_enabled?
  DrbInitializer.start      if AHN_CONFIG.drb_enabled?
  RailsInitializer.start    if AHN_CONFIG.rails_enabled?
  # FreeswitchInitializer.start if AHN_CONFIG.freeswitch_enabled?
end

#initialize_log_fileObject



306
307
308
309
310
311
312
313
314
315
316
# File 'lib/adhearsion/initializer.rb', line 306

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().



356
357
358
359
360
361
362
363
364
365
366
367
368
369
# File 'lib/adhearsion/initializer.rb', line 356

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



256
257
258
259
260
# File 'lib/adhearsion/initializer.rb', line 256

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



342
343
344
345
346
# File 'lib/adhearsion/initializer.rb', line 342

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

#resolve_log_file_pathObject



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

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



153
154
155
156
157
158
159
160
# File 'lib/adhearsion/initializer.rb', line 153

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)


296
297
298
# File 'lib/adhearsion/initializer.rb', line 296

def should_daemonize?
  @daemon || ENV['DAEMON']
end

#startObject



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/adhearsion/initializer.rb', line 123

def start
  self.class.ahn_root = path
  
  resolve_pid_file_path
  resolve_log_file_path
  switch_to_root_directory
  catch_termination_signal
  bootstrap_rc
  daemonize! if should_daemonize?
  initialize_log_file
  load_all_init_files
  init_components_subsystem
  init_modules
  init_events_subsystem
  create_pid_file if pid_file
  load_components
  init_events_file
  
  ahn_log "Adhearsion initialized!"
  
  trigger_after_initialized_hooks
  join_important_threads
  
  self
end

#switch_to_root_directoryObject



167
168
169
# File 'lib/adhearsion/initializer.rb', line 167

def switch_to_root_directory
  Dir.chdir AHN_ROOT
end

#trigger_after_initialized_hooksObject



348
349
350
# File 'lib/adhearsion/initializer.rb', line 348

def trigger_after_initialized_hooks
  Events.trigger_immediately :after_initialized
end