servolux 0.12.0 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +7 -3
- data/History.txt +24 -0
- data/lib/servolux.rb +1 -1
- data/lib/servolux/child.rb +2 -2
- data/lib/servolux/piper.rb +4 -2
- data/lib/servolux/prefork.rb +30 -3
- data/lib/servolux/server.rb +47 -7
- data/lib/servolux/version.rb +1 -1
- data/script/bootstrap +1 -1
- data/spec/prefork_spec.rb +36 -30
- data/spec/server_spec.rb +61 -32
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e69a68c60d72f0b63d0f72ed875dc7f4521e202
|
4
|
+
data.tar.gz: b172073acb33a563d4050f30674b3123c2d05301
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48c6f53a3ee9f8a5f7055e87bb27bbbf359e3c6a8c16e7969ac8b118a3d87441235e98d1253a7e76bae0a89c92cdd67ab2f107ac3c4df493a0413e48e4aa0678
|
7
|
+
data.tar.gz: 1e91faba8537394ecc2b5f3a856261f33e061b26dda3e4e9b449a24fc946b88da4de5fd3466679f0b4cf768a27c0196e2e4aaa60560f51e64446a1d02305b00d
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/History.txt
CHANGED
@@ -1,3 +1,27 @@
|
|
1
|
+
== 0.13.0 / 2017-03-18
|
2
|
+
|
3
|
+
* Minor Enhancements
|
4
|
+
* Using a "self pipe" for signal handling in the Server
|
5
|
+
* Bug Fixes
|
6
|
+
* Test cleanup
|
7
|
+
* Better cleanup of child processes across the board
|
8
|
+
|
9
|
+
== 0.12.0 / 2015-06-07
|
10
|
+
|
11
|
+
* Minor Enhancements
|
12
|
+
* Adding support for a `PidFile` class [pr #19]
|
13
|
+
* Bug Fixes
|
14
|
+
|
15
|
+
== 0.11.0 / 2015-05-29
|
16
|
+
|
17
|
+
* Minor Enhancements
|
18
|
+
* Fixing server shutdown and signal handling in Ruby 2.0 and up [pr #16]
|
19
|
+
* Improving error handling [pr #17]
|
20
|
+
* Added worker options [pr #18]
|
21
|
+
* Added a `boostrap` script for easier development
|
22
|
+
* Bug Fixes
|
23
|
+
* Typo and documentation fixes
|
24
|
+
|
1
25
|
== 0.10.0 / 2012-02-18
|
2
26
|
|
3
27
|
* Minor Enhancements
|
data/lib/servolux.rb
CHANGED
@@ -37,6 +37,6 @@ module Servolux
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
%w[version
|
40
|
+
%w[version threaded child daemon null_logger pid_file piper prefork server].each do |lib|
|
41
41
|
require Servolux.libpath('servolux', lib)
|
42
42
|
end
|
data/lib/servolux/child.rb
CHANGED
@@ -149,7 +149,7 @@ class Servolux::Child
|
|
149
149
|
# the child process is not running.
|
150
150
|
#
|
151
151
|
def wait( flags = 0 )
|
152
|
-
return if @
|
152
|
+
return if @pid.nil?
|
153
153
|
_, @status = Process.wait2(@pid, flags) unless @status
|
154
154
|
exitstatus
|
155
155
|
end
|
@@ -160,7 +160,7 @@ class Servolux::Child
|
|
160
160
|
# @return [Boolean]
|
161
161
|
#
|
162
162
|
def alive?
|
163
|
-
return if @
|
163
|
+
return if @pid.nil?
|
164
164
|
wait(Process::WNOHANG|Process::WUNTRACED)
|
165
165
|
Process.kill(0, @pid)
|
166
166
|
true
|
data/lib/servolux/piper.rb
CHANGED
@@ -69,7 +69,9 @@ class Servolux::Piper
|
|
69
69
|
piper.parent {
|
70
70
|
pid = piper.gets
|
71
71
|
raise ::Servolux::Error, 'Could not get the child PID.' if pid.nil?
|
72
|
-
|
72
|
+
|
73
|
+
piper.wait # reap the child process
|
74
|
+
piper.instance_variable_set(:@child_pid, pid) # adopt the grandchild
|
73
75
|
}
|
74
76
|
piper.child {
|
75
77
|
Process.setsid # Become session leader.
|
@@ -358,7 +360,7 @@ class Servolux::Piper
|
|
358
360
|
wait(Process::WNOHANG|Process::WUNTRACED)
|
359
361
|
Process.kill(0, @child_pid)
|
360
362
|
true
|
361
|
-
rescue Errno::ESRCH, Errno::ENOENT
|
363
|
+
rescue Errno::ESRCH, Errno::ENOENT, Errno::ECHILD
|
362
364
|
false
|
363
365
|
end
|
364
366
|
|
data/lib/servolux/prefork.rb
CHANGED
@@ -209,7 +209,7 @@ class Servolux::Prefork
|
|
209
209
|
# @return [Prefork] self
|
210
210
|
#
|
211
211
|
def reap
|
212
|
-
@workers.each { |worker| worker.
|
212
|
+
@workers.each { |worker| worker.reap }
|
213
213
|
self
|
214
214
|
end
|
215
215
|
|
@@ -261,7 +261,7 @@ class Servolux::Prefork
|
|
261
261
|
# Remove workers that are no longer alive from the worker pool
|
262
262
|
#
|
263
263
|
def prune_workers
|
264
|
-
new_workers = @workers.find_all { |w| w.alive? }
|
264
|
+
new_workers = @workers.find_all { |w| w.reap.alive? }
|
265
265
|
@workers = new_workers
|
266
266
|
end
|
267
267
|
|
@@ -375,6 +375,7 @@ private
|
|
375
375
|
@thread = nil
|
376
376
|
@piper = nil
|
377
377
|
@error = nil
|
378
|
+
@pid_list = []
|
378
379
|
end
|
379
380
|
|
380
381
|
# Start this worker. A new process will be forked, and the code supplied
|
@@ -383,6 +384,7 @@ private
|
|
383
384
|
# @return [Worker] self
|
384
385
|
#
|
385
386
|
def start
|
387
|
+
@pid_list << @piper.pid if @piper
|
386
388
|
@error = nil
|
387
389
|
@piper = ::Servolux::Piper.new('rw', :timeout => @timeout)
|
388
390
|
@piper.parent? ? parent : child
|
@@ -414,7 +416,7 @@ private
|
|
414
416
|
#
|
415
417
|
def wait
|
416
418
|
return if @piper.nil? or @piper.child?
|
417
|
-
@piper.wait(Process::
|
419
|
+
@piper.wait(Process::WUNTRACED)
|
418
420
|
end
|
419
421
|
|
420
422
|
# Send this given _signal_ to the child process. The default signal is
|
@@ -444,6 +446,31 @@ private
|
|
444
446
|
@piper.alive?
|
445
447
|
end
|
446
448
|
|
449
|
+
# Internal: Attempt to reap any child processes spawned by this worker. If a
|
450
|
+
# child has exited, then we remove it from our PID list.
|
451
|
+
#
|
452
|
+
# @return [Worker] this worker instance.
|
453
|
+
def reap
|
454
|
+
@piper.alive? unless @piper.nil?
|
455
|
+
@pid_list.dup.each do |pid|
|
456
|
+
@pid_list.delete(pid) if reap?(pid)
|
457
|
+
end
|
458
|
+
self
|
459
|
+
end
|
460
|
+
|
461
|
+
# Internal: Check the return status of the given child PID. This will reap
|
462
|
+
# the process from the kernel process table if the child has exited.
|
463
|
+
#
|
464
|
+
# @return [Boolean] true if the PID has exited; false otherwise.
|
465
|
+
def reap?(pid)
|
466
|
+
_, cstatus = Process.wait2(pid, Process::WNOHANG|Process::WUNTRACED)
|
467
|
+
return true if cstatus
|
468
|
+
Process.kill(0, pid)
|
469
|
+
false
|
470
|
+
rescue Errno::ESRCH, Errno::ENOENT, Errno::ECHILD
|
471
|
+
true
|
472
|
+
end
|
473
|
+
|
447
474
|
# Returns +true+ if communication with the child process timed out.
|
448
475
|
# Returns +nil+ if the child process has not been started.
|
449
476
|
#
|
data/lib/servolux/server.rb
CHANGED
@@ -193,6 +193,7 @@ class Servolux::Server
|
|
193
193
|
wait_for_shutdown if wait
|
194
194
|
ensure
|
195
195
|
pid_file.delete
|
196
|
+
halt_signal_processing
|
196
197
|
end
|
197
198
|
return self
|
198
199
|
end
|
@@ -259,21 +260,60 @@ class Servolux::Server
|
|
259
260
|
|
260
261
|
private
|
261
262
|
|
263
|
+
def halt_signal_processing
|
264
|
+
if defined?(@wr) && !@wr.nil? && !@wr.closed?
|
265
|
+
@queue << :halt
|
266
|
+
@wr.write("!")
|
267
|
+
@wr.flush
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
262
271
|
def trap_signals
|
272
|
+
@queue = []
|
273
|
+
@rd, @wr = IO.pipe
|
274
|
+
|
263
275
|
SIGNALS.each do |sig|
|
264
276
|
method = sig.downcase.to_sym
|
265
277
|
if self.respond_to? method
|
266
278
|
Signal.trap(sig) do
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
end
|
279
|
+
begin
|
280
|
+
@queue << method
|
281
|
+
@wr.write_nonblock("!")
|
282
|
+
rescue StandardError => err
|
283
|
+
logger.error "Exception in signal handler: #{method}"
|
284
|
+
logger.error err
|
274
285
|
end
|
275
286
|
end
|
276
287
|
end
|
277
288
|
end
|
289
|
+
|
290
|
+
Thread.new {
|
291
|
+
:run while process_signals
|
292
|
+
@rd.close if !@rd.nil? && !@rd.closed?
|
293
|
+
@wr.close if !@wr.nil? && !@wr.closed?
|
294
|
+
logger.info "Signal processing thread has stopped"
|
295
|
+
}
|
296
|
+
end
|
297
|
+
|
298
|
+
def process_signals
|
299
|
+
IO.select([@rd])
|
300
|
+
@rd.read_nonblock(42)
|
301
|
+
|
302
|
+
while !@queue.empty?
|
303
|
+
method = @queue.shift
|
304
|
+
next if method.nil?
|
305
|
+
return false if method == :halt
|
306
|
+
|
307
|
+
self.send(method)
|
308
|
+
end
|
309
|
+
return true
|
310
|
+
rescue IO::WaitReadable
|
311
|
+
return true
|
312
|
+
rescue IOError, EOFError, Errno::EBADF
|
313
|
+
return false
|
314
|
+
rescue StandardError => err
|
315
|
+
logger.error "Exception in signal handler: #{method}"
|
316
|
+
logger.error err
|
317
|
+
return false
|
278
318
|
end
|
279
319
|
end
|
data/lib/servolux/version.rb
CHANGED
data/script/bootstrap
CHANGED
data/spec/prefork_spec.rb
CHANGED
@@ -21,14 +21,17 @@ describe Servolux::Prefork do
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def alive?( pid )
|
24
|
-
_, cstatus = Process.wait2( pid, Process::WNOHANG )
|
25
|
-
return false if cstatus
|
26
24
|
Process.kill(0, pid)
|
27
25
|
true
|
28
26
|
rescue Errno::ESRCH, Errno::ENOENT, Errno::ECHILD
|
29
27
|
false
|
30
28
|
end
|
31
29
|
|
30
|
+
def wait_until( seconds = 5 )
|
31
|
+
start = Time.now
|
32
|
+
sleep 0.250 until ((Time.now - start) > seconds) || yield
|
33
|
+
end
|
34
|
+
|
32
35
|
before :all do
|
33
36
|
tmp = Tempfile.new 'servolux-prefork'
|
34
37
|
@path = tmp.path; tmp.unlink
|
@@ -65,8 +68,8 @@ describe Servolux::Prefork do
|
|
65
68
|
@prefork = Servolux::Prefork.new :module => @worker, :config => {:path => @path}
|
66
69
|
@prefork.start 1
|
67
70
|
ary = workers
|
68
|
-
|
69
|
-
|
71
|
+
wait_until { ary.all? { |w| w.alive? } }
|
72
|
+
wait_until { worker_count >= 1 }
|
70
73
|
|
71
74
|
ary = Dir.glob(@glob)
|
72
75
|
expect(ary.length).to eq(1)
|
@@ -77,8 +80,8 @@ describe Servolux::Prefork do
|
|
77
80
|
@prefork = Servolux::Prefork.new :module => @worker, :config => {:path => @path}
|
78
81
|
@prefork.start 8
|
79
82
|
ary = workers
|
80
|
-
|
81
|
-
|
83
|
+
wait_until { ary.all? { |w| w.alive? } }
|
84
|
+
wait_until { worker_count >= 8 }
|
82
85
|
|
83
86
|
ary = Dir.glob(@glob)
|
84
87
|
expect(ary.length).to eq(8)
|
@@ -91,14 +94,14 @@ describe Servolux::Prefork do
|
|
91
94
|
@prefork = Servolux::Prefork.new :module => @worker, :config => {:path => @path}
|
92
95
|
@prefork.start 3
|
93
96
|
ary = workers
|
94
|
-
|
95
|
-
|
97
|
+
wait_until { ary.all? { |w| w.alive? } }
|
98
|
+
wait_until { worker_count >= 3 }
|
96
99
|
|
97
100
|
ary = Dir.glob(@glob)
|
98
101
|
expect(ary.length).to eq(3)
|
99
102
|
|
100
103
|
@prefork.stop
|
101
|
-
|
104
|
+
wait_until { Dir.glob(@glob).length == 0 }
|
102
105
|
workers.each { |w| w.wait rescue nil }
|
103
106
|
|
104
107
|
rv = workers.all? { |w| !w.alive? }
|
@@ -109,13 +112,14 @@ describe Servolux::Prefork do
|
|
109
112
|
@prefork = Servolux::Prefork.new :module => @worker, :config => {:path => @path}
|
110
113
|
@prefork.start 2
|
111
114
|
ary = workers
|
112
|
-
|
113
|
-
|
115
|
+
wait_until { ary.all? { |w| w.alive? } }
|
116
|
+
wait_until { worker_count >= 2 }
|
114
117
|
|
115
118
|
pid = pids.last
|
116
119
|
ary.last.signal 'HUP'
|
117
|
-
|
118
|
-
|
120
|
+
wait_until { !alive? pid }
|
121
|
+
@prefork.reap
|
122
|
+
wait_until { ary.all? { |w| w.alive? } }
|
119
123
|
|
120
124
|
expect(pid).not_to eq(pids.last)
|
121
125
|
end
|
@@ -124,17 +128,19 @@ describe Servolux::Prefork do
|
|
124
128
|
@prefork = Servolux::Prefork.new :module => @worker, :config => {:path => @path}
|
125
129
|
@prefork.start 2
|
126
130
|
ary = workers
|
127
|
-
|
128
|
-
|
131
|
+
wait_until { ary.all? { |w| w.alive? } }
|
132
|
+
wait_until { worker_count >= 2 }
|
129
133
|
|
130
134
|
pid = pids.last
|
131
135
|
ary.last.signal 'TERM'
|
132
136
|
|
133
|
-
|
137
|
+
wait_until { !alive? pid }
|
138
|
+
@prefork.reap
|
139
|
+
|
134
140
|
@prefork.each_worker do |worker|
|
135
141
|
worker.start unless worker.alive?
|
136
142
|
end
|
137
|
-
|
143
|
+
wait_until { ary.all? { |w| w.alive? } }
|
138
144
|
expect(pid).not_to eq(pids.last)
|
139
145
|
end
|
140
146
|
|
@@ -142,12 +148,12 @@ describe Servolux::Prefork do
|
|
142
148
|
@prefork = Servolux::Prefork.new :module => @worker, :config => {:path => @path}
|
143
149
|
@prefork.start 2
|
144
150
|
ary = workers
|
145
|
-
|
146
|
-
|
151
|
+
wait_until { ary.all? { |w| w.alive? } }
|
152
|
+
wait_until { worker_count >= 2 }
|
147
153
|
|
148
154
|
|
149
155
|
@prefork.add_workers( 2 )
|
150
|
-
|
156
|
+
wait_until { worker_count >= 4 }
|
151
157
|
expect(workers.size).to eq(4)
|
152
158
|
end
|
153
159
|
|
@@ -155,11 +161,11 @@ describe Servolux::Prefork do
|
|
155
161
|
@prefork = Servolux::Prefork.new :module => @worker, :max_workers => 3, :config => {:path => @path}
|
156
162
|
@prefork.start 2
|
157
163
|
ary = workers
|
158
|
-
|
159
|
-
|
164
|
+
wait_until { ary.all? { |w| w.alive? } }
|
165
|
+
wait_until { worker_count >= 2 }
|
160
166
|
|
161
167
|
@prefork.add_workers( 2 )
|
162
|
-
|
168
|
+
wait_until { worker_count >= 3 }
|
163
169
|
expect(workers.size).to eq(3)
|
164
170
|
end
|
165
171
|
|
@@ -167,15 +173,15 @@ describe Servolux::Prefork do
|
|
167
173
|
@prefork = Servolux::Prefork.new :module => @worker, :config => {:path => @path}
|
168
174
|
@prefork.start 2
|
169
175
|
ary = workers
|
170
|
-
|
171
|
-
|
176
|
+
wait_until { ary.all? { |w| w.alive? } }
|
177
|
+
wait_until { worker_count >= 2 }
|
172
178
|
|
173
179
|
@prefork.add_workers( 2 )
|
174
|
-
|
180
|
+
wait_until { worker_count >= 3 }
|
175
181
|
expect(workers.size).to eq(4)
|
176
182
|
|
177
183
|
workers[0].stop
|
178
|
-
|
184
|
+
wait_until { !workers[0].alive? }
|
179
185
|
|
180
186
|
@prefork.prune_workers
|
181
187
|
expect(workers.size).to eq(3)
|
@@ -185,11 +191,11 @@ describe Servolux::Prefork do
|
|
185
191
|
@prefork = Servolux::Prefork.new :module => @worker, :min_workers => 3, :config => {:path => @path}
|
186
192
|
@prefork.start 1
|
187
193
|
ary = workers
|
188
|
-
|
189
|
-
|
194
|
+
wait_until { ary.all? { |w| w.alive? } }
|
195
|
+
wait_until { worker_count >= 1 }
|
190
196
|
|
191
197
|
@prefork.ensure_worker_pool_size
|
192
|
-
|
198
|
+
wait_until { worker_count >= 3 }
|
193
199
|
expect(workers.size).to eq(3)
|
194
200
|
end
|
195
201
|
end
|
data/spec/server_spec.rb
CHANGED
@@ -5,7 +5,11 @@ describe Servolux::Server do
|
|
5
5
|
|
6
6
|
def wait_until( seconds = 5 )
|
7
7
|
start = Time.now
|
8
|
-
sleep 0.250 until (Time.now - start) > seconds
|
8
|
+
sleep 0.250 until ((Time.now - start) > seconds) || yield
|
9
|
+
end
|
10
|
+
|
11
|
+
def readlog
|
12
|
+
@log_output.readline
|
9
13
|
end
|
10
14
|
|
11
15
|
base = Class.new(Servolux::Server) do
|
@@ -23,62 +27,63 @@ describe Servolux::Server do
|
|
23
27
|
after :each do
|
24
28
|
@server.shutdown
|
25
29
|
@server.wait_for_shutdown
|
30
|
+
wait_until { @t.status == false } if @t && @t.alive?
|
26
31
|
end
|
27
32
|
|
28
33
|
it 'generates a PID file' do
|
29
34
|
expect(@server.pid_file).to_not exist
|
30
35
|
|
31
|
-
t = Thread.new {@server.startup}
|
32
|
-
wait_until { @server.running? and t.status == 'sleep' }
|
36
|
+
@t = Thread.new {@server.startup}
|
37
|
+
wait_until { @server.running? and @t.status == 'sleep' }
|
33
38
|
expect(@server.pid_file).to exist
|
34
39
|
|
35
40
|
@server.shutdown
|
36
|
-
wait_until { t.status == false }
|
41
|
+
wait_until { @t.status == false }
|
37
42
|
expect(@server.pid_file).to_not exist
|
38
43
|
end
|
39
44
|
|
40
45
|
it 'generates a PID file with mode rw-r----- by default' do
|
41
|
-
t = Thread.new {@server.startup}
|
42
|
-
wait_until { @server.running? and t.status == 'sleep' }
|
46
|
+
@t = Thread.new {@server.startup}
|
47
|
+
wait_until { @server.running? and @t.status == 'sleep' }
|
43
48
|
expect(@server.pid_file).to exist
|
44
49
|
|
45
|
-
expect(
|
46
|
-
expect(
|
50
|
+
expect(readlog.chomp).to eq(%q(DEBUG Servolux : Writing pid file "./test_server.pid"))
|
51
|
+
expect(readlog.chomp).to eq(%q(DEBUG Servolux : Starting))
|
47
52
|
|
48
53
|
filename = @server.pid_file.filename
|
49
54
|
mode = File.stat(filename).mode & 0777
|
50
55
|
expect(mode).to eq(0640)
|
51
56
|
|
52
57
|
@server.shutdown
|
53
|
-
wait_until { t.status == false }
|
58
|
+
wait_until { @t.status == false }
|
54
59
|
expect(@server.pid_file).to_not exist
|
55
60
|
end
|
56
61
|
|
57
62
|
it 'generates PID file with the specified permissions' do
|
58
63
|
@server.pid_file.mode = 0400
|
59
|
-
t = Thread.new {@server.startup}
|
60
|
-
wait_until { @server.running? and t.status == 'sleep' }
|
64
|
+
@t = Thread.new {@server.startup}
|
65
|
+
wait_until { @server.running? and @t.status == 'sleep' }
|
61
66
|
expect(@server.pid_file).to exist
|
62
67
|
|
63
|
-
expect(
|
64
|
-
expect(
|
68
|
+
expect(readlog.chomp).to eq(%q(DEBUG Servolux : Writing pid file "./test_server.pid"))
|
69
|
+
expect(readlog.chomp).to eq(%q(DEBUG Servolux : Starting))
|
65
70
|
|
66
71
|
filename = @server.pid_file.filename
|
67
72
|
mode = File.stat(filename).mode & 0777
|
68
73
|
expect(mode).to eq(0400)
|
69
74
|
|
70
75
|
@server.shutdown
|
71
|
-
wait_until { t.status == false }
|
76
|
+
wait_until { @t.status == false }
|
72
77
|
expect(@server.pid_file).to_not exist
|
73
78
|
end
|
74
79
|
|
75
80
|
it 'shuts down gracefully when signaled' do
|
76
|
-
t = Thread.new {@server.startup}
|
77
|
-
wait_until { @server.running? and t.status == 'sleep' }
|
81
|
+
@t = Thread.new {@server.startup}
|
82
|
+
wait_until { @server.running? and @t.status == 'sleep' }
|
78
83
|
expect(@server).to be_running
|
79
84
|
|
80
|
-
|
81
|
-
wait_until { t.status == false }
|
85
|
+
Process.kill 'SIGINT', $$
|
86
|
+
wait_until { @t.status == false }
|
82
87
|
expect(@server).to_not be_running
|
83
88
|
end
|
84
89
|
|
@@ -89,31 +94,31 @@ describe Servolux::Server do
|
|
89
94
|
def usr2() logger.info 'usr2 was called'; end
|
90
95
|
end
|
91
96
|
|
92
|
-
t = Thread.new {@server.startup}
|
93
|
-
wait_until { @server.running? and t.status == 'sleep' }
|
94
|
-
|
95
|
-
expect(
|
97
|
+
@t = Thread.new {@server.startup}
|
98
|
+
wait_until { @server.running? and @t.status == 'sleep' }
|
99
|
+
readlog
|
100
|
+
expect(readlog.strip).to eq('DEBUG Servolux : Starting')
|
96
101
|
|
97
102
|
line = nil
|
98
103
|
Process.kill 'SIGUSR1', $$
|
99
|
-
wait_until { line =
|
104
|
+
wait_until { line = readlog }
|
100
105
|
expect(line).to_not be_nil
|
101
106
|
expect(line.strip).to eq('INFO Servolux : usr1 was called')
|
102
107
|
|
103
108
|
line = nil
|
104
109
|
Process.kill 'SIGHUP', $$
|
105
|
-
wait_until { line =
|
110
|
+
wait_until { line = readlog }
|
106
111
|
expect(line).to_not be_nil
|
107
112
|
expect(line.strip).to eq('INFO Servolux : hup was called')
|
108
113
|
|
109
114
|
line = nil
|
110
115
|
Process.kill 'SIGUSR2', $$
|
111
|
-
wait_until { line =
|
116
|
+
wait_until { line = readlog }
|
112
117
|
expect(line).to_not be_nil
|
113
118
|
expect(line.strip).to eq('INFO Servolux : usr2 was called')
|
114
119
|
|
115
120
|
Process.kill 'SIGTERM', $$
|
116
|
-
wait_until { t.status == false }
|
121
|
+
wait_until { @t.status == false }
|
117
122
|
expect(@server).to_not be_running
|
118
123
|
end
|
119
124
|
|
@@ -122,20 +127,44 @@ describe Servolux::Server do
|
|
122
127
|
def usr2() raise 'Ooops!'; end
|
123
128
|
end
|
124
129
|
|
125
|
-
t = Thread.new {@server.startup}
|
126
|
-
wait_until { @server.running? and t.status == 'sleep' }
|
127
|
-
|
128
|
-
expect(
|
130
|
+
@t = Thread.new {@server.startup}
|
131
|
+
wait_until { @server.running? and @t.status == 'sleep' }
|
132
|
+
readlog
|
133
|
+
expect(readlog.strip).to eq('DEBUG Servolux : Starting')
|
129
134
|
|
130
135
|
line = nil
|
131
136
|
Process.kill 'SIGUSR2', $$
|
132
|
-
wait_until { line =
|
137
|
+
wait_until { line = readlog }
|
133
138
|
expect(line).to_not be_nil
|
134
139
|
expect(line.strip).to eq('ERROR Servolux : Exception in signal handler: usr2')
|
135
140
|
|
136
141
|
line = nil
|
137
|
-
wait_until { line =
|
142
|
+
wait_until { line = readlog }
|
138
143
|
expect(line).to_not be_nil
|
139
144
|
expect(line.strip).to eq('ERROR Servolux : <RuntimeError> Ooops!')
|
140
145
|
end
|
146
|
+
|
147
|
+
it 'logs when the signal handler thread exits' do
|
148
|
+
class << @server
|
149
|
+
def hup() logger.info 'hup was called'; end
|
150
|
+
end
|
151
|
+
|
152
|
+
@t = Thread.new {@server.startup}
|
153
|
+
wait_until { @server.running? and @t.status == 'sleep' }
|
154
|
+
readlog
|
155
|
+
expect(readlog.strip).to eq('DEBUG Servolux : Starting')
|
156
|
+
|
157
|
+
line = nil
|
158
|
+
@server.__send__(:halt_signal_processing)
|
159
|
+
wait_until { line = readlog }
|
160
|
+
expect(line).to_not be_nil
|
161
|
+
expect(line.strip).to eq('INFO Servolux : Signal processing thread has stopped')
|
162
|
+
|
163
|
+
line = nil
|
164
|
+
Process.kill 'SIGHUP', $$
|
165
|
+
wait_until { line = readlog }
|
166
|
+
expect(line).to_not be_nil
|
167
|
+
expect(line.strip).to eq('ERROR Servolux : Exception in signal handler: hup')
|
168
|
+
expect(readlog.strip).to eq('ERROR Servolux : <IOError> closed stream')
|
169
|
+
end
|
141
170
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: servolux
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Pease
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-03-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bones-rspec
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 3.8.
|
61
|
+
version: 3.8.4
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 3.8.
|
68
|
+
version: 3.8.4
|
69
69
|
description: |-
|
70
70
|
Serv-O-Lux is a collection of Ruby classes that are useful for daemon and
|
71
71
|
process management, and for writing your own Ruby services. The code is well
|
@@ -127,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
127
|
version: '0'
|
128
128
|
requirements: []
|
129
129
|
rubyforge_project: servolux
|
130
|
-
rubygems_version: 2.
|
130
|
+
rubygems_version: 2.6.8
|
131
131
|
signing_key:
|
132
132
|
specification_version: 4
|
133
133
|
summary: A collection of tools for working with processes
|