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/History.txt +10 -0
- data/README.rdoc +3 -1
- data/examples/beanstalk.rb +33 -8
- data/examples/echo.rb +1 -1
- data/examples/server_beanstalk.rb +84 -0
- data/lib/servolux/child.rb +34 -15
- data/lib/servolux/daemon.rb +66 -52
- data/lib/servolux/piper.rb +71 -34
- data/lib/servolux/prefork.rb +164 -56
- data/lib/servolux/server.rb +9 -4
- data/lib/servolux/threaded.rb +12 -10
- data/lib/servolux.rb +11 -3
- data/spec/piper_spec.rb +1 -1
- data/spec/prefork_spec.rb +125 -0
- data/spec/server_spec.rb +12 -5
- data/spec/threaded_spec.rb +17 -2
- metadata +8 -8
- data/a.rb +0 -34
- data/b.rb +0 -17
data/lib/servolux.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
module Servolux
|
3
3
|
|
4
4
|
# :stopdoc:
|
5
|
-
VERSION = '0.
|
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
|
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
@@ -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', $$)
|
data/spec/threaded_spec.rb
CHANGED
@@ -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
|
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.
|
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.
|
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
|
+
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.
|
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.
|
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.
|
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
|
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