daemon-kit 0.1.7 → 0.1.7.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Configuration.txt +58 -0
- data/History.txt +24 -0
- data/Manifest.txt +50 -2
- data/PostInstall.txt +1 -1
- data/README.rdoc +7 -9
- data/Rakefile +2 -4
- data/TODO.txt +6 -5
- data/app_generators/daemon_kit/daemon_kit_generator.rb +5 -0
- data/app_generators/daemon_kit/templates/Rakefile +3 -1
- data/app_generators/daemon_kit/templates/bin/daemon.erb +1 -1
- data/app_generators/daemon_kit/templates/config/arguments.rb +12 -0
- data/app_generators/daemon_kit/templates/config/boot.rb +2 -2
- data/app_generators/daemon_kit/templates/script/console +3 -0
- data/app_generators/daemon_kit/templates/script/destroy +14 -0
- data/app_generators/daemon_kit/templates/script/generate +14 -0
- data/daemon_generators/amqp/templates/config/amqp.yml +5 -5
- data/daemon_generators/deploy_capistrano/deploy_capistrano_generator.rb +4 -23
- data/daemon_generators/deploy_capistrano/templates/USAGE +10 -0
- data/daemon_generators/deploy_capistrano/templates/config/deploy.rb +3 -1
- data/lib/daemon_kit.rb +33 -5
- data/lib/daemon_kit/amqp.rb +2 -1
- data/lib/daemon_kit/application.rb +136 -11
- data/lib/daemon_kit/arguments.rb +151 -0
- data/lib/daemon_kit/commands/console.rb +38 -0
- data/lib/daemon_kit/config.rb +1 -0
- data/lib/daemon_kit/console_daemon.rb +2 -0
- data/lib/daemon_kit/core_ext.rb +1 -0
- data/lib/daemon_kit/core_ext/string.rb +22 -0
- data/lib/daemon_kit/deployment/capistrano.rb +6 -9
- data/lib/daemon_kit/error_handlers/mail.rb +52 -15
- data/lib/daemon_kit/initializer.rb +95 -41
- data/lib/daemon_kit/pid_file.rb +61 -0
- data/lib/daemon_kit/tasks/environment.rake +5 -4
- data/lib/daemon_kit/tasks/framework.rake +15 -1
- data/lib/daemon_kit/tasks/god.rake +62 -0
- data/lib/daemon_kit/tasks/log.rake +8 -0
- data/lib/daemon_kit/tasks/monit.rake +29 -0
- data/spec/argument_spec.rb +51 -0
- data/spec/config_spec.rb +77 -0
- data/spec/daemon_kit_spec.rb +2 -2
- data/spec/error_handlers_spec.rb +23 -0
- data/spec/fixtures/env.yml +15 -0
- data/spec/fixtures/noenv.yml +4 -0
- data/spec/initializer_spec.rb +4 -3
- data/spec/spec_helper.rb +8 -11
- data/templates/god/god.erb +69 -0
- data/templates/monit/monit.erb +14 -0
- data/test/test_daemon-kit_generator.rb +6 -1
- data/test/test_deploy_capistrano_generator.rb +1 -2
- data/vendor/tmail-1.2.3/tmail.rb +5 -0
- data/vendor/tmail-1.2.3/tmail/address.rb +426 -0
- data/vendor/tmail-1.2.3/tmail/attachments.rb +46 -0
- data/vendor/tmail-1.2.3/tmail/base64.rb +46 -0
- data/vendor/tmail-1.2.3/tmail/compat.rb +41 -0
- data/vendor/tmail-1.2.3/tmail/config.rb +67 -0
- data/vendor/tmail-1.2.3/tmail/core_extensions.rb +63 -0
- data/vendor/tmail-1.2.3/tmail/encode.rb +581 -0
- data/vendor/tmail-1.2.3/tmail/header.rb +960 -0
- data/vendor/tmail-1.2.3/tmail/index.rb +9 -0
- data/vendor/tmail-1.2.3/tmail/interface.rb +1130 -0
- data/vendor/tmail-1.2.3/tmail/loader.rb +3 -0
- data/vendor/tmail-1.2.3/tmail/mail.rb +578 -0
- data/vendor/tmail-1.2.3/tmail/mailbox.rb +495 -0
- data/vendor/tmail-1.2.3/tmail/main.rb +6 -0
- data/vendor/tmail-1.2.3/tmail/mbox.rb +3 -0
- data/vendor/tmail-1.2.3/tmail/net.rb +248 -0
- data/vendor/tmail-1.2.3/tmail/obsolete.rb +132 -0
- data/vendor/tmail-1.2.3/tmail/parser.rb +1476 -0
- data/vendor/tmail-1.2.3/tmail/port.rb +379 -0
- data/vendor/tmail-1.2.3/tmail/quoting.rb +118 -0
- data/vendor/tmail-1.2.3/tmail/require_arch.rb +58 -0
- data/vendor/tmail-1.2.3/tmail/scanner.rb +49 -0
- data/vendor/tmail-1.2.3/tmail/scanner_r.rb +261 -0
- data/vendor/tmail-1.2.3/tmail/stringio.rb +280 -0
- data/vendor/tmail-1.2.3/tmail/utils.rb +337 -0
- data/vendor/tmail-1.2.3/tmail/version.rb +39 -0
- data/vendor/tmail.rb +13 -0
- metadata +57 -18
- data/daemon_generators/deploy_capistrano/USAGE +0 -5
- data/lib/daemon_kit/patches/force_kill_wait.rb +0 -120
data/lib/daemon_kit/config.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/core_ext/string'
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
class String
|
4
|
+
|
5
|
+
# Assuming the string is a file or path name, convert it into an
|
6
|
+
# absolute path.
|
7
|
+
def to_absolute_path
|
8
|
+
# Pathname is incompatible with Windows, but Windows doesn't have
|
9
|
+
# real symlinks so File.expand_path is safe.
|
10
|
+
if RUBY_PLATFORM =~ /(:?mswin|mingw)/
|
11
|
+
File.expand_path( self )
|
12
|
+
|
13
|
+
# Otherwise use Pathname#realpath which respects symlinks.
|
14
|
+
else
|
15
|
+
begin
|
16
|
+
File.expand_path( Pathname.new( self ).realpath.to_s )
|
17
|
+
rescue Errno::ENOENT
|
18
|
+
File.expand_path( Pathname.new( self ).cleanpath.to_s )
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -305,18 +305,15 @@ namespace :deploy do
|
|
305
305
|
end
|
306
306
|
|
307
307
|
desc <<-DESC
|
308
|
-
Restarts your application. This works by calling
|
309
|
-
|
308
|
+
Restarts your application. This works by calling 'stop' task, \
|
309
|
+
followed by the 'start' task.
|
310
310
|
|
311
|
-
|
312
|
-
|
313
|
-
that user. If you are in an environment where you can't use sudo, set \
|
314
|
-
the :use_sudo variable to false:
|
315
|
-
|
316
|
-
set :use_sudo, false
|
311
|
+
See the descriptions for the 'start' and 'stop' tasks for any \
|
312
|
+
additional info.
|
317
313
|
DESC
|
318
314
|
task :restart, :except => { :no_release => true } do
|
319
|
-
|
315
|
+
stop
|
316
|
+
start
|
320
317
|
end
|
321
318
|
|
322
319
|
namespace :rollback do
|
@@ -1,33 +1,66 @@
|
|
1
|
+
require DaemonKit.framework_root + '/vendor/tmail'
|
1
2
|
require 'net/smtp'
|
2
3
|
|
3
4
|
module DaemonKit
|
4
5
|
module ErrorHandlers
|
5
|
-
# Send an email notification of the exception via SMTP
|
6
|
+
# Send an email notification of the exception via SMTP.
|
6
7
|
class Mail < Base
|
7
|
-
|
8
|
+
|
8
9
|
# SMTP hostname
|
9
10
|
@host = 'localhost'
|
10
|
-
|
11
|
-
|
11
|
+
|
12
|
+
# SMTP port
|
13
|
+
@port = 25
|
14
|
+
|
12
15
|
# Recipients of the notification
|
13
16
|
@recipients = []
|
14
|
-
attr_accessor :recipients
|
15
17
|
|
16
18
|
# Subject prefix
|
17
19
|
@prefix = '[DAEMON-KIT]'
|
18
|
-
attr_accessor :prefix
|
19
20
|
|
20
21
|
# Sender address
|
21
22
|
@sender = 'daemon-kit'
|
22
|
-
|
23
|
+
|
24
|
+
# SMTP username
|
25
|
+
@username = nil
|
26
|
+
|
27
|
+
# SMTP password
|
28
|
+
@password = nil
|
29
|
+
|
30
|
+
# Authentication mechanism (:plain, :login, or :cram_md5)
|
31
|
+
@authentication = nil
|
32
|
+
|
33
|
+
# Use TLS?
|
34
|
+
@tls = false
|
35
|
+
|
36
|
+
# Domain used when talking to SMTP server
|
37
|
+
@domain = 'localhost.localdomain'
|
38
|
+
|
39
|
+
class << self
|
40
|
+
attr_accessor :host, :port, :recipients, :prefix, :sender, :username,
|
41
|
+
:password, :authentication, :tls, :domain
|
42
|
+
end
|
43
|
+
|
44
|
+
[ :host, :port, :recipients, :prefix, :sender, :username, :password,
|
45
|
+
:authentication, :tls, :domain ].each do |cm|
|
46
|
+
class_eval(<<-EOM, __FILE__, __LINE__)
|
47
|
+
def #{cm}=( val )
|
48
|
+
self.class.#{cm} = val
|
49
|
+
end
|
50
|
+
EOM
|
51
|
+
end
|
23
52
|
|
24
53
|
def handle_exception( exception )
|
25
|
-
email = <<EOF
|
26
|
-
To: #{self.recipients.map { |r| '<' + r + '>' }.join(', ')}
|
27
|
-
From: <#{self.sender}>
|
28
|
-
Subject: #{self.prefix} #{exception.message}
|
29
|
-
Date: #{Time.now}
|
30
54
|
|
55
|
+
mail = TMail::Mail.new
|
56
|
+
mail.to = self.class.recipients
|
57
|
+
mail.from = self.class.sender
|
58
|
+
mail.subject = "#{self.class.prefix} #{exception.message}"
|
59
|
+
mail.set_content_type 'text', 'plain'
|
60
|
+
mail.mime_version = '1.0'
|
61
|
+
mail.date = Time.now
|
62
|
+
|
63
|
+
mail.body = <<EOF
|
31
64
|
DaemonKit caught an exception inside #{DaemonKit.configuration.daemon_name}.
|
32
65
|
|
33
66
|
Message: #{exception.message}
|
@@ -37,10 +70,14 @@ Backtrace:
|
|
37
70
|
Environment: #{ENV.inspect}
|
38
71
|
EOF
|
39
72
|
begin
|
40
|
-
Net::SMTP.
|
41
|
-
|
73
|
+
smtp = Net::SMTP.new( self.class.host, self.class.port )
|
74
|
+
smtp.enable_starttls_auto if self.class.tls && smtp.respond_to?(:enable_starttls_auto)
|
75
|
+
smtp.start( self.class.domain, self.class.username, self.class.password,
|
76
|
+
self.class.authentication ) do |smtp|
|
77
|
+
smtp.sendmail( mail.to_s, mail.from, mail.to )
|
42
78
|
end
|
43
|
-
rescue
|
79
|
+
rescue => e
|
80
|
+
DaemonKit.logger.error "Failed to send exception mail: #{e.message}" if DaemonKit.logger
|
44
81
|
end
|
45
82
|
end
|
46
83
|
end
|
@@ -3,21 +3,21 @@ require 'pathname'
|
|
3
3
|
|
4
4
|
DAEMON_ENV = (ENV['DAEMON_ENV'] || 'development').dup unless defined?(DAEMON_ENV)
|
5
5
|
|
6
|
-
|
6
|
+
# Absolute paths to the daemon_kit libraries added to $:
|
7
|
+
incdir = ( File.dirname(__FILE__) + '/..' )
|
8
|
+
absincdir = if RUBY_PLATFORM =~ /(:?mswin|mingw)/
|
9
|
+
File.expand_path( incdir )
|
10
|
+
else
|
11
|
+
File.expand_path( Pathname.new( incdir ).realpath.to_s )
|
12
|
+
end
|
13
|
+
$:.unshift absincdir unless $:.include?( absincdir )
|
14
|
+
|
7
15
|
require 'daemon_kit'
|
8
16
|
|
9
17
|
module DaemonKit
|
10
18
|
|
11
19
|
class << self
|
12
20
|
|
13
|
-
def logger
|
14
|
-
@logger
|
15
|
-
end
|
16
|
-
|
17
|
-
def logger=( logger )
|
18
|
-
@logger = logger
|
19
|
-
end
|
20
|
-
|
21
21
|
def configuration
|
22
22
|
@configuration
|
23
23
|
end
|
@@ -26,17 +26,18 @@ module DaemonKit
|
|
26
26
|
@configuration = configuration
|
27
27
|
end
|
28
28
|
|
29
|
-
def
|
30
|
-
|
29
|
+
def arguments
|
30
|
+
@arguments
|
31
31
|
end
|
32
32
|
|
33
|
-
def
|
34
|
-
|
33
|
+
def arguments=( args )
|
34
|
+
@arguments = args
|
35
35
|
end
|
36
36
|
|
37
|
-
def
|
38
|
-
|
37
|
+
def trap( *args, &block )
|
38
|
+
self.configuration.trap( *args, &block )
|
39
39
|
end
|
40
|
+
|
40
41
|
end
|
41
42
|
|
42
43
|
|
@@ -46,7 +47,9 @@ module DaemonKit
|
|
46
47
|
|
47
48
|
attr_reader :configuration
|
48
49
|
|
49
|
-
def self.run
|
50
|
+
def self.run
|
51
|
+
configuration = DaemonKit.configuration || Configuration.new
|
52
|
+
|
50
53
|
yield configuration if block_given?
|
51
54
|
initializer = new configuration
|
52
55
|
initializer.before_daemonize
|
@@ -59,7 +62,7 @@ module DaemonKit
|
|
59
62
|
end
|
60
63
|
|
61
64
|
def self.shutdown
|
62
|
-
DaemonKit.logger.warn "Shutting down"
|
65
|
+
DaemonKit.logger.warn "Shutting down #{DaemonKit.configuration.daemon_name}"
|
63
66
|
exit
|
64
67
|
end
|
65
68
|
|
@@ -83,6 +86,10 @@ module DaemonKit
|
|
83
86
|
|
84
87
|
include_core_lib
|
85
88
|
load_postdaemonize_configs
|
89
|
+
|
90
|
+
set_process_name
|
91
|
+
|
92
|
+
DaemonKit.logger.info( "DaemonKit (#{DaemonKit::VERSION}) booted, now running #{DaemonKit.configuration.daemon_name}" )
|
86
93
|
end
|
87
94
|
|
88
95
|
def set_load_path
|
@@ -96,9 +103,7 @@ module DaemonKit
|
|
96
103
|
end
|
97
104
|
|
98
105
|
def load_patches
|
99
|
-
|
100
|
-
require 'daemon_kit/patches/force_kill_wait'
|
101
|
-
end
|
106
|
+
|
102
107
|
end
|
103
108
|
|
104
109
|
def load_environment
|
@@ -136,6 +141,8 @@ module DaemonKit
|
|
136
141
|
|
137
142
|
DaemonKit.logger = logger
|
138
143
|
|
144
|
+
DaemonKit.logger.info "DaemonKit (#{DaemonKit::VERSION}) booting in #{DAEMON_ENV} mode"
|
145
|
+
|
139
146
|
configuration.trap("USR1") {
|
140
147
|
DaemonKit.logger.level = DaemonKit.logger.debug? ? Logger::INFO : Logger::DEBUG
|
141
148
|
DaemonKit.logger.info "Log level changed to #{DaemonKit.logger.debug? ? 'DEBUG' : 'INFO' }"
|
@@ -144,8 +151,6 @@ module DaemonKit
|
|
144
151
|
DaemonKit.logger.level = Logger::DEBUG
|
145
152
|
DaemonKit.logger.info "Log level changed to DEBUG"
|
146
153
|
}
|
147
|
-
|
148
|
-
DaemonKit.logger.info "DaemonKit up and running in #{DAEMON_ENV} mode"
|
149
154
|
end
|
150
155
|
|
151
156
|
def initialize_signal_traps
|
@@ -159,6 +164,10 @@ module DaemonKit
|
|
159
164
|
require core_lib
|
160
165
|
end
|
161
166
|
end
|
167
|
+
|
168
|
+
def set_process_name
|
169
|
+
$0 = configuration.daemon_name
|
170
|
+
end
|
162
171
|
end
|
163
172
|
|
164
173
|
# Holds our various configuration values
|
@@ -175,21 +184,15 @@ module DaemonKit
|
|
175
184
|
# Path to the log file, defaults to 'log/<environment>.log'
|
176
185
|
attr_accessor :log_path
|
177
186
|
|
178
|
-
# :system,
|
179
|
-
attr_accessor :dir_mode
|
180
|
-
|
181
|
-
# Path to the log file, defaults to 'log/<environment>.log'
|
182
|
-
attr_accessor :dir
|
183
|
-
|
184
187
|
# Provide a custom logger to use
|
185
188
|
attr_accessor :logger
|
186
189
|
|
190
|
+
# Path to the pid file, defaults to 'log/<daemon_name>.pid'
|
191
|
+
attr_accessor :pid_file
|
192
|
+
|
187
193
|
# The application name
|
188
194
|
attr_accessor :daemon_name
|
189
195
|
|
190
|
-
# Allow multiple copies to run?
|
191
|
-
attr_accessor :multiple
|
192
|
-
|
193
196
|
# Use the force kill patch? Give the number of seconds
|
194
197
|
attr_accessor :force_kill_wait
|
195
198
|
|
@@ -200,6 +203,8 @@ module DaemonKit
|
|
200
203
|
attr_accessor :safety_net
|
201
204
|
|
202
205
|
def initialize
|
206
|
+
parse_arguments!
|
207
|
+
|
203
208
|
set_root_path!
|
204
209
|
set_daemon_defaults!
|
205
210
|
|
@@ -207,7 +212,6 @@ module DaemonKit
|
|
207
212
|
self.log_level = default_log_level
|
208
213
|
self.log_path = default_log_path
|
209
214
|
|
210
|
-
self.multiple = false
|
211
215
|
self.force_kill_wait = false
|
212
216
|
|
213
217
|
self.safety_net = DaemonKit::Safety.instance
|
@@ -240,6 +244,10 @@ module DaemonKit
|
|
240
244
|
@signal_traps[signal].unshift( proc || block )
|
241
245
|
end
|
242
246
|
|
247
|
+
def pid_file
|
248
|
+
@pid_file ||= "#{File.dirname(self.log_path)}/#{self.daemon_name}.pid"
|
249
|
+
end
|
250
|
+
|
243
251
|
protected
|
244
252
|
|
245
253
|
def run_traps( signal )
|
@@ -255,28 +263,57 @@ module DaemonKit
|
|
255
263
|
Signal.trap( signal, Proc.new { self.run_traps( signal ) } )
|
256
264
|
end
|
257
265
|
|
266
|
+
def parse_arguments!
|
267
|
+
return unless own_args?
|
268
|
+
|
269
|
+
configs = Arguments.configuration( ARGV ).first
|
270
|
+
@unused_arguments = {}
|
271
|
+
|
272
|
+
configs.each do |c|
|
273
|
+
k,v = c.split('=')
|
274
|
+
|
275
|
+
if v.nil?
|
276
|
+
error( "#{k} has no value" )
|
277
|
+
next
|
278
|
+
end
|
279
|
+
|
280
|
+
begin
|
281
|
+
if self.respond_to?( k )
|
282
|
+
self.send( "#{k}=", v ) # pid_file = /var/run/foo.pid
|
283
|
+
else
|
284
|
+
@unused_arguments[ k ] = v
|
285
|
+
end
|
286
|
+
rescue => e
|
287
|
+
error( "Couldn't set `#{k}' to `#{v}': #{e.message}" )
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
# DANGEROUS: Change the value of DAEMON_ENV
|
293
|
+
def environment=( env )
|
294
|
+
::DAEMON_ENV.replace( env )
|
295
|
+
end
|
296
|
+
|
258
297
|
def set_root_path!
|
259
298
|
raise "DAEMON_ROOT is not set" unless defined?(::DAEMON_ROOT)
|
260
|
-
raise "DAEMON_ROOT is not a directory" unless
|
299
|
+
raise "DAEMON_ROOT is not a directory" unless File.directory?(::DAEMON_ROOT)
|
261
300
|
|
262
|
-
@root_path =
|
301
|
+
@root_path = ::DAEMON_ROOT.to_absolute_path
|
263
302
|
# Pathname is incompatible with Windows, but Windows doesn't have
|
264
303
|
# real symlinks so File.expand_path is safe.
|
265
|
-
if RUBY_PLATFORM =~ /(:?mswin|mingw)/
|
266
|
-
|
304
|
+
#if RUBY_PLATFORM =~ /(:?mswin|mingw)/
|
305
|
+
# File.expand_path(::DAEMON_ROOT)
|
267
306
|
|
268
307
|
# Otherwise use Pathname#realpath which respects symlinks.
|
269
|
-
else
|
270
|
-
|
271
|
-
end
|
308
|
+
#else
|
309
|
+
# File.expand_path( Pathname.new(::DAEMON_ROOT).realpath.to_s )
|
310
|
+
#end
|
272
311
|
|
273
312
|
Object.const_set(:RELATIVE_DAEMON_ROOT, ::DAEMON_ROOT.dup) unless defined?(::RELATIVE_DAEMON_ROOT)
|
274
313
|
::DAEMON_ROOT.replace @root_path
|
275
314
|
end
|
276
315
|
|
277
316
|
def set_daemon_defaults!
|
278
|
-
self.dir_mode = :normal
|
279
|
-
self.dir = File.join( DAEMON_ROOT, 'log' )
|
280
317
|
end
|
281
318
|
|
282
319
|
def default_load_paths
|
@@ -290,6 +327,23 @@ module DaemonKit
|
|
290
327
|
def default_log_level
|
291
328
|
environment == 'production' ? Logger::INFO : Logger::DEBUG
|
292
329
|
end
|
330
|
+
|
331
|
+
def error( msg )
|
332
|
+
msg = "[E] Configuration: #{msg}"
|
333
|
+
|
334
|
+
if DaemonKit.logger
|
335
|
+
DaemonKit.logger.error( msg )
|
336
|
+
else
|
337
|
+
STDERR.puts msg
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
# If we are executed with any of these commands, don't allow
|
342
|
+
# arguments to be parsed cause they will interfere with the
|
343
|
+
# script encapsulating DaemonKit, like capistrano
|
344
|
+
def own_args?
|
345
|
+
![ 'cap' ].include?( File.basename( $0 ) )
|
346
|
+
end
|
293
347
|
end
|
294
348
|
|
295
349
|
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module DaemonKit
|
2
|
+
|
3
|
+
# Simple pidfile handling for daemon processes
|
4
|
+
class PidFile
|
5
|
+
|
6
|
+
def initialize( path )
|
7
|
+
@path = path.to_absolute_path
|
8
|
+
end
|
9
|
+
|
10
|
+
def exists?
|
11
|
+
File.exists?( @path )
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns true if the process is running
|
15
|
+
def running?
|
16
|
+
return false unless self.exists?
|
17
|
+
|
18
|
+
# Check if process is in existence
|
19
|
+
# The simplest way to do this is to send signal '0'
|
20
|
+
# (which is a single system call) that doesn't actually
|
21
|
+
# send a signal
|
22
|
+
begin
|
23
|
+
Process.kill(0, self.pid)
|
24
|
+
return true
|
25
|
+
rescue Errno::ESRCH
|
26
|
+
return false
|
27
|
+
rescue ::Exception # for example on EPERM (process exists but does not belong to us)
|
28
|
+
return true
|
29
|
+
#rescue Errno::EPERM
|
30
|
+
# return false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Return the pid contained in the pidfile, or nil
|
35
|
+
def pid
|
36
|
+
return nil unless self.exists?
|
37
|
+
|
38
|
+
File.open( @path ) { |f|
|
39
|
+
return f.gets.to_i
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def ensure_stopped!
|
44
|
+
if self.running?
|
45
|
+
puts "Process already running with id #{self.pid}"
|
46
|
+
exit 1
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def cleanup
|
51
|
+
File.delete( @path ) rescue Errno::ENOENT
|
52
|
+
end
|
53
|
+
alias zap cleanup
|
54
|
+
|
55
|
+
def write!
|
56
|
+
File.open( @path, 'w' ) { |f|
|
57
|
+
f.puts Process.pid
|
58
|
+
}
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|