pidly 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,8 @@
1
+ === 0.1.3 / 04/07/2011
2
+
3
+ * Refactor callback validations
4
+ * log/pid files now return a Pathname object
5
+
1
6
  === 0.1.2 / 04/07/2011
2
7
 
3
8
  * Callbacks#add_callback should be private
@@ -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
- @path = Pathname.new(options.fetch(:path))
71
+ @path = if options.has_key?(:path)
72
+ Pathname.new(options.fetch(:path))
48
73
  else
49
- @path = Pathname.new('/tmp')
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
- @pid_file = options.fetch(:pid_file)
85
+ @pid_file = if options.has_key?(:pid_file)
86
+ Pathname.new(options.fetch(:pid_file))
62
87
  else
63
- @pid_file = File.join(@path.to_s, 'pids', @name + '.pid')
88
+ Pathname.new(File.join(@path.to_s, 'pids', @name + '.pid'))
64
89
  end
65
90
 
66
- if options.has_key?(:log_file)
67
- @log_file = options.fetch(:log_path)
91
+ @log_file = if options.has_key?(:log_file)
92
+ Pathname.new(options.fetch(:log_file))
68
93
  else
69
- @log_file = File.join(@path.to_s, 'logs', @name + '.log')
94
+ Pathname.new(File.join(@path.to_s, 'logs', @name + '.log'))
70
95
  end
71
96
 
72
- @pid = fetch_pid if File.file?(@pid_file)
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 The options to create a controller with.
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
- def validate_files_and_paths!
288
- log = Pathname.new(@log_file).dirname
289
- pid = Pathname.new(@pid_file).dirname
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
- unless File.directory?(log)
292
- FileUtils.mkdir_p(log.to_s)
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 File.directory?(pid)
296
- FileUtils.mkdir_p(pid.to_s)
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
- unless Control.class_variable_defined?(:"@@start")
302
- raise('You must define a "start" callback.')
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
 
@@ -1,4 +1,4 @@
1
1
  module Pidly
2
2
  # pidly version
3
- VERSION = "0.1.2"
3
+ VERSION = "0.1.3"
4
4
  end
@@ -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
@@ -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
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: pidly
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.2
5
+ version: 0.1.3
6
6
  platform: ruby
7
7
  authors:
8
8
  - Dustin Willis Webber