pidly 0.1.2 → 0.1.3
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/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
|