servolux 0.8.1 → 0.9.0

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/lib/servolux.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  module Servolux
3
3
 
4
4
  # :stopdoc:
5
- VERSION = '0.8.1'
5
+ VERSION = '0.9.0'
6
6
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
7
7
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
8
8
  # :startdoc:
@@ -12,6 +12,8 @@ module Servolux
12
12
 
13
13
  # Returns the version string for the library.
14
14
  #
15
+ # @return [String]
16
+ #
15
17
  def self.version
16
18
  VERSION
17
19
  end
@@ -20,25 +22,31 @@ module Servolux
20
22
  # they will be joined to the end of the libray path using
21
23
  # <tt>File.join</tt>.
22
24
  #
25
+ # @return [String] absolute servolux 'lib' path
26
+ #
23
27
  def self.libpath( *args )
24
28
  args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
25
29
  end
26
30
 
27
31
  # Returns the lpath for the module. If any arguments are given,
28
- # they will be joined to the end of the path using
32
+ # they will be joined to the end of the servolux base path using
29
33
  # <tt>File.join</tt>.
30
34
  #
35
+ # @return [String] absolute servolux base path
36
+ #
31
37
  def self.path( *args )
32
38
  args.empty? ? PATH : ::File.join(PATH, args.flatten)
33
39
  end
34
40
 
35
41
  # Returns +true+ if the execution platform supports fork.
36
42
  #
43
+ # @return [Boolean]
44
+ #
37
45
  def self.fork?
38
46
  RUBY_PLATFORM != 'java' and test(?e, '/dev/null')
39
47
  end
40
48
 
41
- end # module Servolux
49
+ end
42
50
 
43
51
  %w[threaded server piper daemon child prefork].each do |lib|
44
52
  require Servolux.libpath('servolux', lib)
data/spec/piper_spec.rb CHANGED
@@ -102,7 +102,7 @@ describe Servolux::Piper do
102
102
  }
103
103
 
104
104
  @piper.parent {
105
- @piper.gets.should == 1
105
+ @piper.gets.should_not == Process.pid
106
106
  }
107
107
  end
108
108
 
@@ -0,0 +1,125 @@
1
+
2
+ require File.join(File.dirname(__FILE__), %w[spec_helper])
3
+ require 'tempfile'
4
+ require 'fileutils'
5
+ require 'enumerator'
6
+
7
+ if Servolux.fork?
8
+
9
+ describe Servolux::Prefork do
10
+
11
+ def pids
12
+ workers.map! { |w| w.instance_variable_get(:@piper).pid }
13
+ end
14
+
15
+ def workers
16
+ ary = []
17
+ return ary if @prefork.nil?
18
+ @prefork.each_worker { |w| ary << w }
19
+ ary
20
+ end
21
+
22
+ def worker_count
23
+ Dir.glob(@glob).length
24
+ end
25
+
26
+ def alive?( pid )
27
+ Process.kill(0, pid)
28
+ true
29
+ rescue Errno::ESRCH, Errno::ENOENT
30
+ false
31
+ end
32
+
33
+ before :all do
34
+ tmp = Tempfile.new 'servolux-prefork'
35
+ @path = path = tmp.path; tmp.unlink
36
+ @glob = @path + '/*.txt'
37
+ FileUtils.mkdir @path
38
+
39
+ @worker = Module.new {
40
+ define_method(:before_executing) { @fd = File.open(path + "/#$$.txt", 'w') }
41
+ def after_executing() @fd.close; FileUtils.rm_f @fd.path; end
42
+ def execute() @fd.puts Time.now; sleep 2; end
43
+ def hup() @thread.wakeup; end
44
+ alias :term :hup
45
+ }
46
+ end
47
+
48
+ after :all do
49
+ FileUtils.rm_rf @path
50
+ end
51
+
52
+ before :each do
53
+ @prefork = nil
54
+ FileUtils.rm_f "#@path/*.txt"
55
+ end
56
+
57
+ after :each do
58
+ next if @prefork.nil?
59
+ @prefork.stop
60
+ @prefork.each_worker { |worker| worker.signal('KILL') }
61
+ @prefork = nil
62
+ FileUtils.rm_f "#@path/*.txt"
63
+ end
64
+
65
+ it "starts up a single worker" do
66
+ @prefork = Servolux::Prefork.new :module => @worker
67
+ @prefork.start 1
68
+ ary = workers
69
+ sleep 0.1 until ary.all? { |w| w.alive? }
70
+ sleep 0.1 until worker_count >= 1
71
+
72
+ ary = Dir.glob(@glob)
73
+ ary.length.should == 1
74
+ File.basename(ary.first).to_i.should == pids.first
75
+ end
76
+
77
+ it "starts up a number of workers" do
78
+ @prefork = Servolux::Prefork.new :module => @worker
79
+ @prefork.start 8
80
+ ary = workers
81
+ sleep 0.250 until ary.all? { |w| w.alive? }
82
+ sleep 0.250 until worker_count >= 8
83
+
84
+ ary = Dir.glob(@glob)
85
+ ary.length.should == 8
86
+
87
+ ary.map! { |fn| File.basename(fn).to_i }.sort!
88
+ ary.should == pids.sort
89
+ end
90
+
91
+ it "stops workers gracefullly" do
92
+ @prefork = Servolux::Prefork.new :module => @worker
93
+ @prefork.start 3
94
+ ary = workers
95
+ sleep 0.250 until ary.all? { |w| w.alive? }
96
+ sleep 0.250 until worker_count >= 3
97
+
98
+ ary = Dir.glob(@glob)
99
+ ary.length.should == 3
100
+
101
+ @prefork.stop
102
+ sleep 0.250 until Dir.glob(@glob).length == 0
103
+
104
+ rv = workers.all? { |w| !w.alive? }
105
+ rv.should == true
106
+ end
107
+
108
+ it "restarts a worker via SIGHUP" do
109
+ @prefork = Servolux::Prefork.new :module => @worker
110
+ @prefork.start 2
111
+ ary = workers
112
+ sleep 0.250 until ary.all? { |w| w.alive? }
113
+ sleep 0.250 until worker_count >= 2
114
+
115
+ pid = pids.last
116
+ ary.last.signal 'HUP'
117
+ @prefork.reap until !alive? pid
118
+ sleep 0.250 until ary.all? { |w| w.alive? }
119
+
120
+ pid.should_not == pids.last
121
+ end
122
+
123
+ end
124
+ end # Servolux.fork?
125
+
data/spec/server_spec.rb CHANGED
@@ -15,6 +15,7 @@ describe Servolux::Server do
15
15
  end
16
16
 
17
17
  after :each do
18
+ @server.shutdown
18
19
  File.delete @server.pid_file if test(?f, @server.pid_file)
19
20
  end
20
21
 
@@ -22,7 +23,7 @@ describe Servolux::Server do
22
23
  test(?e, @server.pid_file).should be_false
23
24
 
24
25
  t = Thread.new {@server.startup}
25
- Thread.pass until @server.status == 'sleep'
26
+ Thread.pass until @server.running? and t.status == 'sleep'
26
27
  test(?e, @server.pid_file).should be_true
27
28
 
28
29
  @server.shutdown
@@ -32,20 +33,26 @@ describe Servolux::Server do
32
33
 
33
34
  it 'generates a PID file with mode rw-r----- by default' do
34
35
  t = Thread.new {@server.startup}
35
- Thread.pass until @server.status == 'sleep'
36
+ Thread.pass until @server.running? and t.status == 'sleep'
37
+
38
+ @log_output.readline.chomp.should == %q(DEBUG Servolux : Server "Test Server" creating pid file "test_server.pid")
39
+ @log_output.readline.chomp.should == %q(DEBUG Servolux : Starting)
36
40
  (File.stat(@server.pid_file).mode & 0777).should == 0640
37
41
  end
38
42
 
39
43
  it 'generates PID file with the specified permissions' do
40
44
  @server.pid_file_mode = 0400
41
45
  t = Thread.new {@server.startup}
42
- Thread.pass until @server.status == 'sleep'
46
+ Thread.pass until @server.running? and t.status == 'sleep'
47
+
48
+ @log_output.readline.chomp.should == %q(DEBUG Servolux : Server "Test Server" creating pid file "test_server.pid")
49
+ @log_output.readline.chomp.should == %q(DEBUG Servolux : Starting)
43
50
  (File.stat(@server.pid_file).mode & 0777).should == 0400
44
51
  end
45
52
 
46
53
  it 'shuts down gracefully when signaled' do
47
54
  t = Thread.new {@server.startup}
48
- Thread.pass until @server.status == 'sleep'
55
+ Thread.pass until @server.running? and t.status == 'sleep'
49
56
  @server.running?.should be_true
50
57
 
51
58
  Process.kill('INT', $$)
@@ -61,7 +68,7 @@ describe Servolux::Server do
61
68
  end
62
69
 
63
70
  t = Thread.new {@server.startup}
64
- Thread.pass until @server.status == 'sleep'
71
+ Thread.pass until @server.running? and t.status == 'sleep'
65
72
  @log_output.readline
66
73
 
67
74
  Process.kill('USR1', $$)
@@ -7,10 +7,23 @@ describe Servolux::Threaded do
7
7
  include Servolux::Threaded
8
8
  def initialize
9
9
  self.interval = 0
10
+ @mutex = Mutex.new
11
+ @signal = ConditionVariable.new
10
12
  end
11
13
  def pass( val = 'sleep' )
12
14
  Thread.pass until status == val
13
15
  end
16
+ def send_signal
17
+ @mutex.synchronize {
18
+ @signal.signal
19
+ @signal = nil
20
+ }
21
+ end
22
+ def wait_signal
23
+ @mutex.synchronize {
24
+ @signal.wait(@mutex) unless @signal.nil?
25
+ }
26
+ end
14
27
  end
15
28
 
16
29
  it "let's you know that it is running" do
@@ -93,7 +106,9 @@ describe Servolux::Threaded do
93
106
  klass = Class.new(base) do
94
107
  def run()
95
108
  @sleep ||= false
96
- if @sleep then sleep
109
+ if @sleep
110
+ send_signal
111
+ sleep
97
112
  else
98
113
  @sleep = true
99
114
  raise 'ni'
@@ -105,7 +120,7 @@ describe Servolux::Threaded do
105
120
  obj.continue_on_error = true
106
121
 
107
122
  obj.start
108
- obj.pass
123
+ obj.wait_signal
109
124
 
110
125
  obj.running?.should be_true
111
126
  @log_output.readline
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: servolux
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Pease
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-12 00:00:00 -07:00
12
+ date: 2009-11-30 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -20,7 +20,7 @@ dependencies:
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 1.1.0
23
+ version: 1.2.0
24
24
  version:
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: bones-git
@@ -30,7 +30,7 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 1.0.0
33
+ version: 1.1.1
34
34
  version:
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: logging
@@ -50,7 +50,7 @@ dependencies:
50
50
  requirements:
51
51
  - - ">="
52
52
  - !ruby/object:Gem::Version
53
- version: 1.2.8
53
+ version: 1.2.9
54
54
  version:
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bones
@@ -60,7 +60,7 @@ dependencies:
60
60
  requirements:
61
61
  - - ">="
62
62
  - !ruby/object:Gem::Version
63
- version: 3.0.1
63
+ version: 3.1.0
64
64
  version:
65
65
  description: |-
66
66
  Serv-O-Lux is a collection of Ruby classes that are useful for daemon and
@@ -79,10 +79,9 @@ files:
79
79
  - History.txt
80
80
  - README.rdoc
81
81
  - Rakefile
82
- - a.rb
83
- - b.rb
84
82
  - examples/beanstalk.rb
85
83
  - examples/echo.rb
84
+ - examples/server_beanstalk.rb
86
85
  - lib/servolux.rb
87
86
  - lib/servolux/child.rb
88
87
  - lib/servolux/daemon.rb
@@ -92,6 +91,7 @@ files:
92
91
  - lib/servolux/threaded.rb
93
92
  - spec/child_spec.rb
94
93
  - spec/piper_spec.rb
94
+ - spec/prefork_spec.rb
95
95
  - spec/server_spec.rb
96
96
  - spec/servolux_spec.rb
97
97
  - spec/spec_helper.rb
data/a.rb DELETED
@@ -1,34 +0,0 @@
1
-
2
- $LOAD_PATH.unshift 'lib'
3
-
4
- require 'servolux'
5
-
6
- STDOUT.sync = true
7
-
8
-
9
- module DoThis
10
- def before_executing
11
- @fd = File.open("#$$.txt", 'w')
12
- end
13
-
14
- def after_executing
15
- STDOUT.puts "Closing #$$.txt"
16
- @fd.close
17
- end
18
-
19
- def execute
20
- @fd.puts "Process #$$ @ #{Time.now}"
21
- sleep 2
22
- end
23
- end
24
-
25
- p = Servolux::Prefork.new :module => DoThis
26
- p.start 6
27
- gets
28
- p.stop
29
-
30
- p.errors { |w|
31
- puts w.error.inspect
32
- }
33
-
34
- Process.waitall
data/b.rb DELETED
@@ -1,17 +0,0 @@
1
-
2
- $LOAD_PATH.unshift 'lib'
3
-
4
- require 'servolux'
5
- STDOUT.sync = true
6
-
7
- p = Servolux::Prefork.new {
8
- puts "Process #$$ @ #{Time.now}"
9
- sleep
10
- }
11
- p.start 12
12
- sleep 30
13
- p.stop
14
-
15
- p.errors { |e|
16
- puts e.inspect
17
- }