servolux 0.8.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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
- }