pidly 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog.rdoc +5 -0
- data/lib/pidly/control.rb +87 -65
- data/lib/pidly/version.rb +1 -1
- data/spec/control_spec.rb +29 -4
- data/spec/spec_helper.rb +23 -0
- metadata +1 -1
data/ChangeLog.rdoc
CHANGED
data/lib/pidly/control.rb
CHANGED
@@ -29,6 +29,31 @@ module Pidly
|
|
29
29
|
#
|
30
30
|
# @param [Hash] options The options to create a controller with.
|
31
31
|
#
|
32
|
+
# @option options [String] :name Daemon name
|
33
|
+
#
|
34
|
+
# @option options [String] :path Path to create the log/pids directory
|
35
|
+
#
|
36
|
+
# @option options [String] :pid_file Pid file path
|
37
|
+
#
|
38
|
+
# @option options [String] :log_file Log file path
|
39
|
+
#
|
40
|
+
# @option options [true, false] :sync_log Synchronize log files
|
41
|
+
#
|
42
|
+
# @option options [true, false] :allow_multiple
|
43
|
+
# Allow multiple daemons of the same type
|
44
|
+
#
|
45
|
+
# @option options [true, false] :sync_log Synchronize log files
|
46
|
+
#
|
47
|
+
# @option options [String] :signal Trap signal
|
48
|
+
#
|
49
|
+
# @option options [Integer] :timeout Timeout for Process#wait
|
50
|
+
#
|
51
|
+
# @option options [true, false] :verbose Display daemon messages
|
52
|
+
#
|
53
|
+
# @option options [true, false] :logger Enable daemon logging
|
54
|
+
#
|
55
|
+
# @return [Control] Control object
|
56
|
+
#
|
32
57
|
# @raise [RuntimeError]
|
33
58
|
# Raise exception if path does not exist
|
34
59
|
#
|
@@ -43,10 +68,10 @@ module Pidly
|
|
43
68
|
|
44
69
|
@name = options.fetch(:name)
|
45
70
|
|
46
|
-
if options.has_key?(:path)
|
47
|
-
|
71
|
+
@path = if options.has_key?(:path)
|
72
|
+
Pathname.new(options.fetch(:path))
|
48
73
|
else
|
49
|
-
|
74
|
+
Pathname.new('/tmp')
|
50
75
|
end
|
51
76
|
|
52
77
|
unless @path.directory?
|
@@ -57,19 +82,19 @@ module Pidly
|
|
57
82
|
raise('Path must be readable and writable.')
|
58
83
|
end
|
59
84
|
|
60
|
-
if options.has_key?(:pid_file)
|
61
|
-
|
85
|
+
@pid_file = if options.has_key?(:pid_file)
|
86
|
+
Pathname.new(options.fetch(:pid_file))
|
62
87
|
else
|
63
|
-
|
88
|
+
Pathname.new(File.join(@path.to_s, 'pids', @name + '.pid'))
|
64
89
|
end
|
65
90
|
|
66
|
-
if options.has_key?(:log_file)
|
67
|
-
|
91
|
+
@log_file = if options.has_key?(:log_file)
|
92
|
+
Pathname.new(options.fetch(:log_file))
|
68
93
|
else
|
69
|
-
|
94
|
+
Pathname.new(File.join(@path.to_s, 'logs', @name + '.log'))
|
70
95
|
end
|
71
96
|
|
72
|
-
@pid = fetch_pid
|
97
|
+
@pid = fetch_pid
|
73
98
|
|
74
99
|
@sync_log = options.fetch(:sync_log, true)
|
75
100
|
|
@@ -82,38 +107,27 @@ module Pidly
|
|
82
107
|
@verbosity = options.fetch(:verbose, true)
|
83
108
|
|
84
109
|
@logger = options.fetch(:logger, true)
|
110
|
+
|
111
|
+
validate_callbacks!
|
112
|
+
|
113
|
+
validate_files_and_paths!
|
85
114
|
end
|
86
115
|
|
87
116
|
#
|
88
117
|
# Spawn
|
89
|
-
#
|
90
|
-
# @param [Hash] options
|
91
|
-
#
|
92
|
-
# @option options [String] :name Daemon name
|
93
|
-
#
|
94
|
-
# @option options [String] :path Path to create the log/pids directory
|
95
|
-
#
|
96
|
-
# @option options [String] :pid_file Pid file path
|
97
|
-
#
|
98
|
-
# @option options [String] :log_file Log file path
|
99
|
-
#
|
100
|
-
# @option options [true, false] :sync_log Synchronize log files
|
101
|
-
#
|
102
|
-
# @option options [true, false] :allow_multiple
|
103
|
-
# Allow multiple daemons of the same type
|
104
|
-
#
|
105
|
-
# @option options [true, false] :sync_log Synchronize log files
|
106
|
-
#
|
107
|
-
# @option options [String] :signal Trap signal
|
108
|
-
#
|
109
|
-
# @option options [Integer] :timeout Timeout for Process#wait
|
110
|
-
#
|
111
|
-
# @option options [true, false] :verbose Display daemon messages
|
112
|
-
#
|
113
|
-
# @option options [true, false] :logger Enable daemon logging
|
118
|
+
#
|
119
|
+
# @param [Hash] options Control object options
|
114
120
|
#
|
115
121
|
# @return [Control] Control object
|
116
122
|
#
|
123
|
+
# @see initialize
|
124
|
+
#
|
125
|
+
# @example
|
126
|
+
# Test.spawn(
|
127
|
+
# :path => '/tmp',
|
128
|
+
# :verbose => true
|
129
|
+
# )
|
130
|
+
#
|
117
131
|
def self.spawn(options={})
|
118
132
|
@daemon = new(options)
|
119
133
|
end
|
@@ -124,8 +138,6 @@ module Pidly
|
|
124
138
|
# Validate callbacks and start daemon
|
125
139
|
#
|
126
140
|
def start
|
127
|
-
validate_files_and_paths!
|
128
|
-
validate_callbacks!
|
129
141
|
|
130
142
|
unless @allow_multiple
|
131
143
|
if running?
|
@@ -284,22 +296,50 @@ module Pidly
|
|
284
296
|
rescue Errno::ENOENT
|
285
297
|
end
|
286
298
|
|
287
|
-
|
288
|
-
|
289
|
-
|
299
|
+
#
|
300
|
+
# Fetch Class Variable
|
301
|
+
#
|
302
|
+
# @param [Symbol] name Callback name
|
303
|
+
#
|
304
|
+
# @return [Symbol, Proc, nil]
|
305
|
+
# Returns either a method or block of code to be executed when
|
306
|
+
# the callback is called. If no value is accossiated with the
|
307
|
+
# call variable `nil` will be returned to the caller.
|
308
|
+
#
|
309
|
+
def fetch_class_var(name)
|
310
|
+
Control.instance_eval do
|
311
|
+
return nil unless class_variable_defined?(:"@@#{name}")
|
312
|
+
|
313
|
+
class_variable_get(:"@@#{name}")
|
314
|
+
end
|
315
|
+
end
|
290
316
|
|
291
|
-
|
292
|
-
|
317
|
+
def validate_files_and_paths!
|
318
|
+
unless @log_file.directory?
|
319
|
+
FileUtils.mkdir_p(@log_file.dirname)
|
293
320
|
end
|
294
321
|
|
295
|
-
unless
|
296
|
-
FileUtils.mkdir_p(
|
322
|
+
unless @pid_file.directory?
|
323
|
+
FileUtils.mkdir_p(@pid_file.dirname)
|
297
324
|
end
|
298
325
|
end
|
299
326
|
|
300
327
|
def validate_callbacks!
|
301
|
-
|
302
|
-
|
328
|
+
parent = self
|
329
|
+
Control.instance_eval do
|
330
|
+
|
331
|
+
unless class_variable_defined?(:"@@start")
|
332
|
+
raise('You must define a "start" callback.')
|
333
|
+
end
|
334
|
+
|
335
|
+
class_variables.each do |cvar|
|
336
|
+
value = class_variable_get(:"#{cvar}")
|
337
|
+
|
338
|
+
next unless value.is_a?(Symbol)
|
339
|
+
next if parent.respond_to?(value)
|
340
|
+
|
341
|
+
raise("Undefined callback method: #{value}")
|
342
|
+
end
|
303
343
|
end
|
304
344
|
end
|
305
345
|
|
@@ -309,23 +349,14 @@ module Pidly
|
|
309
349
|
if (callback = fetch_class_var(callback_name))
|
310
350
|
|
311
351
|
if callback.kind_of?(Symbol)
|
312
|
-
|
313
|
-
unless self.respond_to?(callback.to_sym)
|
314
|
-
raise("Undefined callback method: #{callback}")
|
315
|
-
end
|
316
|
-
|
317
352
|
self.send(callback.to_sym)
|
318
|
-
|
319
353
|
elsif callback.respond_to?(:call)
|
320
|
-
|
321
354
|
self.instance_eval(&callback)
|
322
|
-
|
323
355
|
else
|
324
356
|
nil
|
325
357
|
end
|
326
358
|
|
327
359
|
end
|
328
|
-
|
329
360
|
end
|
330
361
|
|
331
362
|
def fetch_pid
|
@@ -334,17 +365,8 @@ module Pidly
|
|
334
365
|
nil
|
335
366
|
end
|
336
367
|
|
337
|
-
def fetch_class_var(name)
|
338
|
-
if Control.class_variable_defined?(:"@@#{name}")
|
339
|
-
Control.instance_eval do
|
340
|
-
return class_variable_get(:"@@#{name}")
|
341
|
-
end
|
342
|
-
end
|
343
|
-
end
|
344
|
-
|
345
368
|
private :validate_callbacks!, :fetch_pid,
|
346
|
-
:validate_files_and_paths!, :execute_callback
|
347
|
-
:fetch_class_var
|
369
|
+
:validate_files_and_paths!, :execute_callback
|
348
370
|
|
349
371
|
end # class Control
|
350
372
|
|
data/lib/pidly/version.rb
CHANGED
data/spec/control_spec.rb
CHANGED
@@ -20,12 +20,13 @@ describe Control do
|
|
20
20
|
|
21
21
|
it "should have an active status, name and pid" do
|
22
22
|
@daemon.status
|
23
|
-
reply = "#{@daemon.name} is running (PID #{@daemon.pid})"
|
23
|
+
reply = "\"#{@daemon.name}\" is running (PID: #{@daemon.pid})"
|
24
|
+
|
24
25
|
@daemon.messages.last.should == reply
|
25
26
|
end
|
26
27
|
|
27
28
|
it "should have the correct pid path" do
|
28
|
-
@daemon.pid_file.should == "/tmp/pids/#{@daemon.name}.pid"
|
29
|
+
@daemon.pid_file.to_s.should == "/tmp/pids/#{@daemon.name}.pid"
|
29
30
|
end
|
30
31
|
|
31
32
|
it "should have a pid file that exists" do
|
@@ -33,7 +34,7 @@ describe Control do
|
|
33
34
|
end
|
34
35
|
|
35
36
|
it "should have the correct log file" do
|
36
|
-
@daemon.log_file.should == "/tmp/logs/#{@daemon.name}.log"
|
37
|
+
@daemon.log_file.to_s.should == "/tmp/logs/#{@daemon.name}.log"
|
37
38
|
end
|
38
39
|
|
39
40
|
it "should have a log file that exists" do
|
@@ -42,7 +43,7 @@ describe Control do
|
|
42
43
|
|
43
44
|
it "should fail when trying to start another daemon" do
|
44
45
|
@daemon.start
|
45
|
-
reply = "#{@daemon.name} is already running (PID #{@daemon.pid})"
|
46
|
+
reply = "\"#{@daemon.name}\" is already running (PID: #{@daemon.pid})"
|
46
47
|
|
47
48
|
@daemon.messages.last.should == reply
|
48
49
|
end
|
@@ -56,6 +57,30 @@ describe Control do
|
|
56
57
|
file = File.open(@daemon.pid_file, 'r')
|
57
58
|
file.read.should =~ /#{@daemon.pid}/
|
58
59
|
end
|
60
|
+
|
61
|
+
it "should not have a start callback defined" do
|
62
|
+
test_callback(:start, true).should == true
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should not have a stop callback defined" do
|
66
|
+
test_callback(:stop).should == "Attempting to kill process: "
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should not have a before_start callback defined" do
|
70
|
+
test_callback(:before_start).should == "BEFORE START "
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should not have a after_stop callback defined" do
|
74
|
+
test_callback(:after_stop).should == :test_after_daemon_stops
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should have an error callback defined" do
|
78
|
+
test_callback(:error).should == "SENDING EMAIL | Error Count: "
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should not have a kill callback defined" do
|
82
|
+
test_callback(:kill).should == nil
|
83
|
+
end
|
59
84
|
|
60
85
|
after(:all) do
|
61
86
|
if @daemon
|
data/spec/spec_helper.rb
CHANGED
@@ -29,5 +29,28 @@ class Test < Pidly::Control
|
|
29
29
|
sleep 2
|
30
30
|
end
|
31
31
|
end
|
32
|
+
|
33
|
+
def test_after_daemon_stops
|
34
|
+
puts "AFTER STOP"
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
32
38
|
|
39
|
+
def test_callback(callback, defined=false)
|
40
|
+
test = @daemon.fetch_class_var(callback.to_sym)
|
41
|
+
|
42
|
+
if defined
|
43
|
+
return true if test
|
44
|
+
false
|
45
|
+
else
|
46
|
+
|
47
|
+
if test.kind_of?(Symbol)
|
48
|
+
test
|
49
|
+
elsif test.respond_to?(:call)
|
50
|
+
test.call
|
51
|
+
else
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
33
56
|
end
|