Class: DaemonKit::Initializer

Inherits:
Object
  • Object
show all
Defined in:
lib/daemon_kit/initializer.rb

Overview

This class does all the nightmare work of setting up a working environment for your daemon.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(configuration) ⇒ Initializer

Returns a new instance of Initializer.



84
85
86
# File 'lib/daemon_kit/initializer.rb', line 84

def initialize( configuration )
  @configuration = configuration
end

Instance Attribute Details

#configurationObject (readonly)

Returns the value of attribute configuration.



47
48
49
# File 'lib/daemon_kit/initializer.rb', line 47

def configuration
  @configuration
end

Class Method Details

.continue!Object



58
59
60
61
# File 'lib/daemon_kit/initializer.rb', line 58

def self.continue!
  initializer = new DaemonKit.configuration
  initializer.after_daemonize
end

.log_exceptionsObject



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/daemon_kit/initializer.rb', line 213

def self.log_exceptions
  trace_file = File.join( DaemonKit.root, 'log', "backtrace-#{Time.now.strftime('%Y%m%d%H%M%S')}-#{Process.pid}.log" )
  trace_log = Logger.new( trace_file )

  # Find the last exception
  e = nil
  ObjectSpace.each_object {|o|
    if ::Exception === o
      e = o
    end
  }

  trace_log.info "*** Below you'll find the most recent exception thrown, this will likely (but not certainly) be the exception that made #{DaemonKit.configuration.daemon_name} exit abnormally ***"
  trace_log.error e

  trace_log.info "*** Below you'll find all the exception objects in memory, some of them may have been thrown in your application, others may just be in memory because they are standard exceptions ***"
  ObjectSpace.each_object {|o|
    if ::Exception === o
      trace_log.error o
    end
  }

  trace_log.close
end

.run {|configuration| ... } ⇒ Object

Yields:



49
50
51
52
53
54
55
56
# File 'lib/daemon_kit/initializer.rb', line 49

def self.run
  configuration = DaemonKit.configuration || Configuration.new

  yield configuration if block_given?
  initializer = new configuration
  initializer.before_daemonize
  initializer
end

.shutdown(clean = false, do_exit = false) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/daemon_kit/initializer.rb', line 63

def self.shutdown( clean = false, do_exit = false )
  return unless $daemon_kit_shutdown_hooks_ran.nil?
  $daemon_kit_shutdown_hooks_ran = true

  DaemonKit.logger.info "Running shutdown hooks"

  DaemonKit.configuration.shutdown_hooks.each do |hook|
    begin
      hook.call
    rescue => e
      DaemonKit.logger.exception( e )
    end
  end

  log_exceptions if DaemonKit.configuration.backtraces && !clean

  DaemonKit.logger.warn "Shutting down #{DaemonKit.configuration.daemon_name}"

  exit if do_exit
end

Instance Method Details

#after_daemonizeObject



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/daemon_kit/initializer.rb', line 98

def after_daemonize
  set_umask

  initialize_logger
  initialize_signal_traps

  include_core_lib
  load_postdaemonize_configs
  configure_backtraces

  set_process_name

  DaemonKit.logger.info( "DaemonKit (#{DaemonKit::VERSION}) booted, now running #{DaemonKit.configuration.daemon_name}" )

  if DaemonKit.configuration.user || DaemonKit.configuration.group
    euid = Process.euid
    egid = Process.egid
    uid = Process.uid
    gid = Process.gid
    DaemonKit.logger.info( "DaemonKit dropped privileges to: #{euid} (EUID), #{egid} (EGID), #{uid} (UID), #{gid} (GID)"  )
  end
end

#before_daemonizeObject



88
89
90
91
92
93
94
95
96
# File 'lib/daemon_kit/initializer.rb', line 88

def before_daemonize
  DaemonKit.configuration = @configuration

  set_load_path
  load_gems
  load_patches
  load_environment
  load_predaemonize_configs
end

#configure_backtracesObject



205
206
207
# File 'lib/daemon_kit/initializer.rb', line 205

def configure_backtraces
  Thread.abort_on_exception = configuration.backtraces
end

#include_core_libObject



199
200
201
202
203
# File 'lib/daemon_kit/initializer.rb', line 199

def include_core_lib
  if File.exists?( core_lib = File.join( DAEMON_ROOT, 'lib', configuration.daemon_name + '.rb' ) )
    require core_lib
  end
end

#initialize_loggerObject



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/daemon_kit/initializer.rb', line 165

def initialize_logger
  return if DaemonKit.logger

  unless logger = configuration.logger
    logger = AbstractLogger.new( configuration.log_path )
    logger.level = configuration.log_level
    logger.copy_to_stdout = configuration.log_stdout
  end

  DaemonKit.logger = logger

  DaemonKit.logger.info "DaemonKit (#{DaemonKit::VERSION}) booting in #{DAEMON_ENV} mode"

  configuration.trap("USR1") {
    DaemonKit.logger.level = DaemonKit.logger.debug? ? :info : :debug
    DaemonKit.logger.info "Log level changed to #{DaemonKit.logger.debug? ? 'DEBUG' : 'INFO' }"
  }
  configuration.trap("USR2") {
    DaemonKit.logger.level = :debug
    DaemonKit.logger.info "Log level changed to DEBUG"
  }
  configuration.trap("HUP") {
    DaemonKit::Application.reopen_logs
  }
end

#initialize_signal_trapsObject



191
192
193
194
195
196
197
# File 'lib/daemon_kit/initializer.rb', line 191

def initialize_signal_traps
  # Only exit the process if we're not in the 'test' environment
  term_proc = Proc.new { DaemonKit::Initializer.shutdown( true, DAEMON_ENV != 'test' ) }
  configuration.trap( 'INT', term_proc )
  configuration.trap( 'TERM', term_proc )
  at_exit { DaemonKit::Initializer.shutdown }
end

#load_environmentObject



135
136
137
138
139
140
141
142
143
144
145
# File 'lib/daemon_kit/initializer.rb', line 135

def load_environment
  # Needs to be global to prevent loading the files twice
  return if $_daemon_environment_loaded
  $_daemon_environment_loaded = true

  config = configuration

  eval(IO.read(configuration.environment_path), binding, configuration.environment_path)

  eval(IO.read(configuration.daemon_initializer), binding, configuration.daemon_initializer) if File.exist?( configuration.daemon_initializer )
end

#load_gemsObject



127
128
129
# File 'lib/daemon_kit/initializer.rb', line 127

def load_gems

end

#load_patchesObject



131
132
133
# File 'lib/daemon_kit/initializer.rb', line 131

def load_patches

end

#load_postdaemonize_configsObject



155
156
157
158
159
# File 'lib/daemon_kit/initializer.rb', line 155

def load_postdaemonize_configs
  Dir[ File.join( DAEMON_ROOT, 'config', 'post-daemonize', '*.rb' ) ].each do |f|
    require f
  end
end

#load_predaemonize_configsObject



147
148
149
150
151
152
153
# File 'lib/daemon_kit/initializer.rb', line 147

def load_predaemonize_configs
  Dir[ File.join( DAEMON_ROOT, 'config', 'pre-daemonize', '*.rb' ) ].each do |f|
    next if File.basename( f ) == File.basename( configuration.daemon_initializer )

    require f
  end
end

#set_load_pathObject



121
122
123
124
125
# File 'lib/daemon_kit/initializer.rb', line 121

def set_load_path
  configuration.load_paths.each do |d|
    $:.unshift( "#{DAEMON_ROOT}/#{d}" ) if File.directory?( "#{DAEMON_ROOT}/#{d}" )
  end
end

#set_process_nameObject



209
210
211
# File 'lib/daemon_kit/initializer.rb', line 209

def set_process_name
  $0 = configuration.daemon_name
end

#set_umaskObject



161
162
163
# File 'lib/daemon_kit/initializer.rb', line 161

def set_umask
  File.umask configuration.umask
end