daemon-kit 0.1.8.1 → 0.1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +16 -4
- data/Gemfile +4 -0
- data/History.txt +8 -0
- data/README.rdoc +3 -3
- data/Rakefile +3 -25
- data/Upgrading.md +21 -0
- data/bin/daemon-kit +1 -1
- data/daemon-kit.gemspec +36 -256
- data/lib/daemon_kit.rb +2 -2
- data/lib/daemon_kit/arguments.rb +3 -3
- data/lib/daemon_kit/commands/console.rb +1 -1
- data/lib/daemon_kit/deployment/capistrano.rb +7 -39
- data/lib/daemon_kit/dk_amqp.rb +1 -1
- data/lib/daemon_kit/initializer.rb +14 -37
- data/lib/daemon_kit/ruote_participants.rb +9 -2
- data/lib/daemon_kit/ruote_workitem.rb +6 -6
- data/lib/daemon_kit/version.rb +6 -0
- data/lib/generators/daemon_kit/amqp/templates/config/pre-daemonize/amqp.rb +0 -1
- data/lib/generators/daemon_kit/amqp/templates/libexec/%app_name%-daemon.rb +1 -1
- data/lib/generators/daemon_kit/app/templates/Gemfile +5 -0
- data/lib/generators/daemon_kit/app/templates/config/boot.rb +2 -8
- data/lib/generators/daemon_kit/app/templates/config/environment.rb.tt +0 -4
- data/lib/generators/daemon_kit/app/templates/config/pre-daemonize/safely.rb +13 -0
- data/lib/generators/daemon_kit/capistrano/templates/config/deploy.rb.tt +5 -4
- data/lib/generators/daemon_kit/ruote/templates/config/pre-daemonize/ruote.rb +0 -1
- data/spec/initializer_spec.rb +2 -2
- data/spec/spec_helper.rb +2 -3
- data/tasks/rspec.rake +5 -6
- metadata +123 -49
- data/lib/daemon_kit/error_handlers/base.rb +0 -32
- data/lib/daemon_kit/error_handlers/hoptoad.rb +0 -180
- data/lib/daemon_kit/safety.rb +0 -84
- data/spec/error_handlers_spec.rb +0 -23
data/lib/daemon_kit/arguments.rb
CHANGED
@@ -57,7 +57,7 @@ module DaemonKit
|
|
57
57
|
# #Configuration instance are listed below:
|
58
58
|
#
|
59
59
|
# -e value or --env value => environment
|
60
|
-
# --
|
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
|
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
|
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
|
-
|
248
|
+
Symlinks any shared configuration files from :deploy_to/config into \
|
258
249
|
the current release's config directory. Original files, if present, \
|
259
|
-
|
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
|
-
|
267
|
-
|
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 "
|
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 "
|
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
|
-
|
data/lib/daemon_kit/dk_amqp.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
107
|
+
configure_safely
|
107
108
|
|
108
109
|
set_process_name
|
109
110
|
|
110
|
-
DaemonKit.logger.info( "DaemonKit (#{DaemonKit
|
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
|
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
|
206
|
-
Thread.abort_on_exception =
|
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
|
272
|
-
configurable :backtraces,
|
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 = ::
|
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
|
-
::
|
94
|
+
::AMQP::Channel.new.queue( destination_queue, :durable => true ).publish( response.to_json )
|
95
95
|
|
96
96
|
response
|
97
97
|
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
|
-
|
7
|
-
|
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
|
-
#
|
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
|
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
|
|