daemon-kit 0.1.8.1 → 0.1.8.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -57,7 +57,7 @@ module DaemonKit
57
57
  # #Configuration instance are listed below:
58
58
  #
59
59
  # -e value or --env value => environment
60
- # --pid pidfile => pid_file
60
+ # --pidfile pidfile => pid_file
61
61
  # -l path or --log path => /path/to/log/file
62
62
  #
63
63
  def configuration( argv )
@@ -83,7 +83,7 @@ module DaemonKit
83
83
  next
84
84
  end
85
85
 
86
- if argv[i] == "--pidfile"
86
+ if argv[i] == "--pidfile" || argv[i] == "--pid"
87
87
  argv.delete_at( i )
88
88
  configs << "pid_file=#{argv.delete_at(i)}"
89
89
  next
@@ -147,7 +147,7 @@ module DaemonKit
147
147
 
148
148
  opts.separator "Common options:"
149
149
  opts.on("-v", "--version", "Show version information and exit") do
150
- puts "daemon-kit #{DaemonKit::VERSION} (http://github.com/kennethkalmer/daemon-kit)"
150
+ puts "daemon-kit #{DaemonKit.version} (http://github.com/kennethkalmer/daemon-kit)"
151
151
  exit
152
152
  end
153
153
 
@@ -33,6 +33,6 @@ ENV['DAEMON_ENV'] = case ARGV.first
33
33
  ARGV.first || ENV['DAEMON_ENV'] || 'development'
34
34
  end
35
35
 
36
- puts "Loading #{ENV['DAEMON_ENV']} environment (daemon-kit #{DaemonKit::VERSION})"
36
+ puts "Loading #{ENV['DAEMON_ENV']} environment (daemon-kit #{DaemonKit.version})"
37
37
 
38
38
  exec "#{options[:irb]} #{libs} --simple-prompt"
@@ -67,11 +67,6 @@ _cset(:run_method) { fetch(:use_sudo, true) ? :sudo : :run }
67
67
  # standalone case, or during deployment.
68
68
  _cset(:latest_release) { exists?(:deploy_timestamped) ? release_path : current_release }
69
69
 
70
- # =========================================================================
71
- # Variables for bundler
72
- # =========================================================================
73
- _cset(:use_bundler, true)
74
-
75
70
  # =========================================================================
76
71
  # These are helper methods that will be available to your recipes.
77
72
  # =========================================================================
@@ -203,16 +198,12 @@ namespace :deploy do
203
198
  control software you are using (it defaults to :subversion), and the \
204
199
  :deploy_via variable to the strategy you want to use to deploy (it \
205
200
  defaults to :checkout).
206
-
207
- Your bundles will also be installed/updated as part of this step. \
208
- You can disable bundler on remote reployments with the :user_bundler \
209
201
  variable.
210
202
  DESC
211
203
  task :update_code, :except => { :no_release => true } do
212
204
  on_rollback { run "rm -rf #{release_path}; true" }
213
205
  strategy.deploy!
214
206
  finalize_update
215
- bundler.bundle_new_release if fetch(:use_bundler, true)
216
207
  end
217
208
 
218
209
  desc <<-DESC
@@ -254,17 +245,18 @@ namespace :deploy do
254
245
  end
255
246
 
256
247
  desc <<-DESC
257
- Copies any shared configuration files from :deploy_to/config into \
248
+ Symlinks any shared configuration files from :deploy_to/config into \
258
249
  the current release's config directory. Original files, if present, \
259
- are renamed to the same name with .orig appended.
250
+ will be overwritten.
260
251
 
261
252
  Specify a list of files by setting :config_files to an array in your \
262
253
  deployment configuration.
263
254
  DESC
264
255
  task :copy_configs do
265
256
  fetch(:config_files, []).each do |f|
266
- run "[ -f #{release_path}/config/#{f} ]; mv #{release_path}/config/#{f} #{release_path}/config/#{f}.orig"
267
- run "[ -f #{deploy_to}/config/#{f} ]; cp #{deploy_to}/config/#{f} #{release_path}/config/#{f}"
257
+ master_config_file = "#{deploy_to}/config/#{f}"
258
+
259
+ run "if [ -f #{master_config_file} ]; then ln -nsf #{master_config_file} #{current_release}/config/#{f}; fi"
268
260
  end
269
261
  end
270
262
 
@@ -408,8 +400,6 @@ namespace :deploy do
408
400
  task :check, :except => { :no_release => true } do
409
401
  dependencies = strategy.check!
410
402
 
411
- depend( :remote, :gem, "bundler", ">= 0.9.26" ) if fetch(:use_bundler, true)
412
-
413
403
  other = fetch(:dependencies, {})
414
404
  other.each do |location, types|
415
405
  types.each do |type, calls|
@@ -456,7 +446,7 @@ namespace :deploy do
456
446
  the :use_sudo variable to false.
457
447
  DESC
458
448
  task :start do
459
- try_runner "/usr/bin/env DAEMON_ENV=#{fetch(:daemon_env)} #{current_path}/bin/#{application} start"
449
+ try_runner "DAEMON_ENV=#{fetch(:daemon_env)} BUNDLE_GEMFILE=#{current_path}/Gemfile bundle exec #{current_path}/bin/#{application} start"
460
450
  end
461
451
 
462
452
  desc <<-DESC
@@ -468,7 +458,7 @@ namespace :deploy do
468
458
  the :use_sudo variable to false.
469
459
  DESC
470
460
  task :stop do
471
- try_runner "/usr/bin/env DAEMON_ENV=#{fetch(:daemon_env)} #{current_path}/bin/#{application} stop"
461
+ try_runner "DAEMON_ENV=#{fetch(:daemon_env)} BUNDLE_GEMFILE=#{current_path}/Gemfile bundle exec #{current_path}/bin/#{application} stop"
472
462
  end
473
463
 
474
464
  namespace :pending do
@@ -492,25 +482,3 @@ namespace :deploy do
492
482
  end
493
483
  end
494
484
  end
495
-
496
- namespace :bundler do
497
- task :create_symlink, :roles => :app do
498
- shared_dir = File.join(shared_path, 'bundle')
499
- release_dir = File.join(current_release, '.bundle')
500
- run("mkdir -p #{shared_dir} && ln -s #{shared_dir} #{release_dir}")
501
- end
502
-
503
- task :bundle_new_release, :roles => :app do
504
- bundler.create_symlink
505
- run "cd #{release_path} && bundle install .bundle --without test"
506
- end
507
-
508
- task :lock, :roles => :app do
509
- run "cd #{current_release} && bundle lock;"
510
- end
511
-
512
- task :unlock, :roles => :app do
513
- run "cd #{current_release} && bundle unlock;"
514
- end
515
- end
516
-
@@ -1,5 +1,5 @@
1
1
  require 'yaml'
2
- require 'mq'
2
+ require 'amqp'
3
3
 
4
4
  module DaemonKit
5
5
  # Thin wrapper around the amqp gem, specifically designed to ease
@@ -8,6 +8,7 @@ $LOAD_PATH.unshift( File.expand_path('../', __FILE__).to_absolute_path ) unless
8
8
  $LOAD_PATH.include?( File.expand_path('../', __FILE__).to_absolute_path )
9
9
 
10
10
  require 'daemon_kit'
11
+ require 'safely'
11
12
 
12
13
  module DaemonKit
13
14
 
@@ -74,7 +75,7 @@ module DaemonKit
74
75
  end
75
76
  end
76
77
 
77
- log_exceptions if DaemonKit.configuration.backtraces && !clean
78
+ Safely::Backtrace.safe_shutdown! if DaemonKit.configuration.backtraces && clean
78
79
 
79
80
  DaemonKit.logger.warn "Shutting down #{DaemonKit.configuration.daemon_name}"
80
81
 
@@ -103,11 +104,11 @@ module DaemonKit
103
104
 
104
105
  include_core_lib
105
106
  load_postdaemonize_configs
106
- configure_backtraces
107
+ configure_safely
107
108
 
108
109
  set_process_name
109
110
 
110
- DaemonKit.logger.info( "DaemonKit (#{DaemonKit::VERSION}) booted, now running #{DaemonKit.configuration.daemon_name}" )
111
+ DaemonKit.logger.info( "DaemonKit (#{DaemonKit.version}) booted, now running #{DaemonKit.configuration.daemon_name}" )
111
112
 
112
113
  if DaemonKit.configuration.user || DaemonKit.configuration.group
113
114
  euid = Process.euid
@@ -173,7 +174,7 @@ module DaemonKit
173
174
 
174
175
  DaemonKit.logger = logger
175
176
 
176
- DaemonKit.logger.info "DaemonKit (#{DaemonKit::VERSION}) booting in #{DAEMON_ENV} mode"
177
+ DaemonKit.logger.info "DaemonKit (#{DaemonKit.version}) booting in #{DAEMON_ENV} mode"
177
178
 
178
179
  configuration.trap("USR1") {
179
180
  DaemonKit.logger.level = DaemonKit.logger.debug? ? :info : :debug
@@ -202,38 +203,19 @@ module DaemonKit
202
203
  end
203
204
  end
204
205
 
205
- def configure_backtraces
206
- Thread.abort_on_exception = configuration.backtraces
206
+ def configure_safely
207
+ Thread.abort_on_exception = true
208
+
209
+ Safely::Strategy::Log.logger = DaemonKit.logger
210
+
211
+ Safely::Backtrace.trace_directory = File.join( DAEMON_ROOT, "log" )
212
+ Safely::Backtrace.enable!
207
213
  end
208
214
 
209
215
  def set_process_name
210
216
  $0 = configuration.daemon_name
211
217
  end
212
218
 
213
- def self.log_exceptions
214
- trace_file = File.join( DaemonKit.root, 'log', "backtrace-#{Time.now.strftime('%Y%m%d%H%M%S')}-#{Process.pid}.log" )
215
- trace_log = Logger.new( trace_file )
216
-
217
- # Find the last exception
218
- e = nil
219
- ObjectSpace.each_object {|o|
220
- if ::Exception === o
221
- e = o
222
- end
223
- }
224
-
225
- 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 ***"
226
- trace_log.error e
227
-
228
- 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 ***"
229
- ObjectSpace.each_object {|o|
230
- if ::Exception === o
231
- trace_log.error o
232
- end
233
- }
234
-
235
- trace_log.close
236
- end
237
219
  end
238
220
 
239
221
  # Holds our various configuration values
@@ -268,8 +250,8 @@ module DaemonKit
268
250
  # Use the force kill patch? Give the number of seconds
269
251
  configurable :force_kill_wait
270
252
 
271
- # Should be log backtraces
272
- configurable :backtraces, false
253
+ # Should we log backtraces
254
+ configurable :backtraces, true
273
255
 
274
256
  # Configurable umask
275
257
  configurable :umask, 0022
@@ -283,9 +265,6 @@ module DaemonKit
283
265
  # Collection of signal traps
284
266
  attr_reader :signal_traps
285
267
 
286
- # Our safety net (#Safety) instance
287
- attr_accessor :safety_net
288
-
289
268
  # :nodoc: Shutdown hooks
290
269
  attr_reader :shutdown_hooks
291
270
 
@@ -301,8 +280,6 @@ module DaemonKit
301
280
 
302
281
  self.force_kill_wait = false
303
282
 
304
- self.safety_net = DaemonKit::Safety.instance
305
-
306
283
  @signal_traps = {}
307
284
  @shutdown_hooks = []
308
285
  end
@@ -36,6 +36,7 @@ module DaemonKit
36
36
  @transports = []
37
37
  @participants = {}
38
38
  @runtime_queues = []
39
+ @amqp_reply_queue = 'ruote_workitems'
39
40
 
40
41
  @configuration = Config.load('ruote')
41
42
  end
@@ -54,6 +55,12 @@ module DaemonKit
54
55
  @transports << transport
55
56
  end
56
57
 
58
+ # Set the name of the AMQP queue that a remote RuoteAMQP::Receiver is listening
59
+ # to (defaults to 'ruote_workitems')
60
+ def amqp_reply_queue( name )
61
+ @amqp_reply_queue = name
62
+ end
63
+
57
64
  # Register classes as pseudo-participants. Two styles of registration are
58
65
  # supported:
59
66
  #
@@ -90,7 +97,7 @@ module DaemonKit
90
97
 
91
98
  def run_amqp!
92
99
  AMQP.run do
93
- mq = ::MQ.new
100
+ mq = ::AMQP::Channel.new
94
101
  queues = @configuration['amqp']['queues'].to_a | @runtime_queues
95
102
 
96
103
  queues.each do |q|
@@ -101,7 +108,7 @@ module DaemonKit
101
108
  safely do
102
109
  DaemonKit.logger.debug("Received workitem: #{message.inspect}")
103
110
 
104
- RuoteWorkitem.process( :amqp, message )
111
+ RuoteWorkitem.process( :amqp, @amqp_reply_queue, message )
105
112
 
106
113
  DaemonKit.logger.debug("Processed workitem.")
107
114
 
@@ -36,7 +36,7 @@ module DaemonKit
36
36
  # the error information:
37
37
  #
38
38
  # daemon_kit.error
39
- def process( transport, workitem )
39
+ def process( transport, from, workitem )
40
40
  # keep it singleton
41
41
  @instance ||= new
42
42
 
@@ -64,7 +64,7 @@ module DaemonKit
64
64
  work["__error__"] = msg
65
65
  end
66
66
 
67
- reply_to_engine( transport, work )
67
+ reply_to_engine( transport, from, work )
68
68
  end
69
69
 
70
70
  # Extract the class and method name from the workitem, then pick the matching
@@ -85,13 +85,13 @@ module DaemonKit
85
85
  return instance, method
86
86
  end
87
87
 
88
- def reply_to_engine( transport, response )
89
- send( "reply_via_#{transport}", response )
88
+ def reply_to_engine( transport, from, response )
89
+ send( "reply_via_#{transport}", from, response )
90
90
  end
91
91
 
92
- def reply_via_amqp( response )
92
+ def reply_via_amqp( destination_queue, response )
93
93
  DaemonKit.logger.debug("Replying to engine via AMQP with #{response.inspect}")
94
- ::MQ.queue( response['params']['reply_queue'] ).publish( response.to_json )
94
+ ::AMQP::Channel.new.queue( destination_queue, :durable => true ).publish( response.to_json )
95
95
 
96
96
  response
97
97
  end
@@ -0,0 +1,6 @@
1
+ module DaemonKit
2
+ def version
3
+ '0.1.8.2'
4
+ end
5
+ module_function :version
6
+ end
@@ -1,6 +1,5 @@
1
1
  begin
2
2
  require 'amqp'
3
- require 'mq'
4
3
  rescue LoadError
5
4
  $stderr.puts "Missing amqp gem. Please run 'bundle install'."
6
5
  exit 1
@@ -30,7 +30,7 @@ DaemonKit::AMQP.run do
30
30
  # end
31
31
  # end
32
32
 
33
- amq = ::MQ.new
33
+ amq = AMQP::Channel.new
34
34
  amq.queue('test').subscribe do |msg|
35
35
  DaemonKit.logger.debug "Received message: #{msg.inspect}"
36
36
  end
@@ -9,4 +9,9 @@ source :gemcutter
9
9
  # daemon-kit
10
10
  gem 'daemon-kit'
11
11
 
12
+ # safely (http://github.com/kennethkalmer/safely)
13
+ gem 'safely'
14
+ # gem 'toadhopper' # For reporting exceptions to hoptoad
15
+ # gem 'mail' # For reporting exceptions via mail
16
+
12
17
  # For more information on bundler, please visit http://gembundler.com
@@ -3,14 +3,8 @@
3
3
 
4
4
  DAEMON_ROOT = "#{File.expand_path(File.dirname(__FILE__))}/.." unless defined?( DAEMON_ROOT )
5
5
 
6
- # Use Bundler (preferred)
7
- begin
8
- require File.expand_path('../../.bundle/environment', __FILE__)
9
- rescue LoadError
10
- require 'rubygems'
11
- require 'bundler'
12
- Bundler.setup
13
- end
6
+ require "rubygems"
7
+ require "bundler/setup"
14
8
 
15
9
  module DaemonKit
16
10
  class << self
@@ -19,8 +19,4 @@ DaemonKit::Initializer.run do |config|
19
19
 
20
20
  # Log backraces when a thread/daemon dies (Recommended)
21
21
  # config.backtraces = true
22
-
23
- # Configure the safety net (see DaemonKit::Safety)
24
- # config.safety_net.handler = :hoptoad
25
- # config.safety_net.hoptoad.api_key = ''
26
22
  end
@@ -0,0 +1,13 @@
1
+ # Safely is responsible for providing exception reporting and the
2
+ # logging of backtraces when your daemon dies unexpectedly. The full
3
+ # documentation for safely can be found at
4
+ # http://github.com/kennethkalmer/safely/wiki
5
+
6
+ # By default Safely will use the daemon-kit's logger to log exceptions,
7
+ # and will store backtraces in the "log" directory.
8
+
9
+ # Comment out to enable Hoptoad support
10
+ # Safely::Strategy::Hoptoad.hoptoad_key = ""
11
+
12
+ # Comment out to use email exceptions
13
+ # Safely::Strategy::Mail.recipient = "your.name@gmail.com"
@@ -23,9 +23,7 @@ set :git_enable_submodules, 1
23
23
  # No sudo
24
24
  set :use_sudo, false
25
25
 
26
- # File list in the config_files setting will be copied from the
27
- # 'deploy_to' directory into config, overwriting files from the repo
28
- # with the same name
26
+ # See `cap -e deploy:copy_configs`
29
27
  set :config_files, %w{}
30
28
 
31
29
  # List any work directories here that you need persisted between
@@ -35,7 +33,7 @@ set :shared_children, %w{log tmp}
35
33
 
36
34
  # Record our dependencies
37
35
  unless File.directory?( "#{DaemonKit.root}/vendor/daemon_kit" )
38
- depend :remote, :gem, "daemon-kit", ">=#{DaemonKit::VERSION}"
36
+ depend :remote, :gem, "daemon-kit", ">=#{DaemonKit.version}"
39
37
  end
40
38
 
41
39
  # Hook into capistrano's events
@@ -44,6 +42,9 @@ before "deploy:update_code", "deploy:check"
44
42
  # Setup log rotation support with every deploy (safe)
45
43
  #after 'deploy:symlink', 'deploy:logrotate'
46
44
 
45
+ # Switch me off if you don't want Bundler integration
46
+ require "bundler/capistrano"
47
+
47
48
  # Create some tasks related to deployment
48
49
  namespace :deploy do
49
50
 
@@ -7,7 +7,6 @@ end
7
7
 
8
8
  begin
9
9
  require 'amqp'
10
- require 'mq'
11
10
  rescue LoadError
12
11
  $stderr.puts "Missing amqp gem. Please uncomment the amqp section in the Gemfile and run 'bundle install' if you wish to use the AMQP participant/listener pair in ruote"
13
12
  end