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