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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 581567ae92a495cdeb92737c979d52e6bd8cf996
4
- data.tar.gz: 0f887e81fc0a8b78e1f340578f2183b460a27ca7
3
+ metadata.gz: 2e69a68c60d72f0b63d0f72ed875dc7f4521e202
4
+ data.tar.gz: b172073acb33a563d4050f30674b3123c2d05301
5
5
  SHA512:
6
- metadata.gz: b67919d827ef8ca1e956918d631bbb2a1ffebcedf3334c4197664c674f340910c0156b6973e476f62c1030069a49332752c7847fab262ee219f633260d971e3f
7
- data.tar.gz: 4cb69e76d39fece3215048a9032bfa3904888061dc1676b818500bca238503f0659e67ee583d98efd9286caf2abc30ccf0e27b283c8deccc62b5e1ec5fe3c558
6
+ metadata.gz: 48c6f53a3ee9f8a5f7055e87bb27bbbf359e3c6a8c16e7969ac8b118a3d87441235e98d1253a7e76bae0a89c92cdd67ab2f107ac3c4df493a0413e48e4aa0678
7
+ data.tar.gz: 1e91faba8537394ecc2b5f3a856261f33e061b26dda3e4e9b449a24fc946b88da4de5fd3466679f0b4cf768a27c0196e2e4aaa60560f51e64446a1d02305b00d
data/.gitignore CHANGED
@@ -15,6 +15,7 @@ announcement.txt
15
15
  coverage
16
16
  doc
17
17
  pkg
18
+ tags
18
19
  .yardoc
19
20
  .rvmrc
20
21
  vendor
@@ -1,11 +1,15 @@
1
1
  language: ruby
2
2
 
3
+ notifications:
4
+ email: false
5
+
3
6
  before_install: "gem install bones"
4
7
  install: "rake gem:install_dependencies"
5
8
 
6
9
  script: "rake"
7
10
 
8
11
  rvm:
9
- - 1.9.3
10
- - 2.1.5
11
- - 2.2.2
12
+ - 2.1.10
13
+ - 2.2.6
14
+ - 2.3.3
15
+ - 2.4.0
@@ -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
@@ -37,6 +37,6 @@ module Servolux
37
37
  end
38
38
  end
39
39
 
40
- %w[version null_logger threaded pid_file server piper daemon child prefork].each do |lib|
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
@@ -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 @io.nil?
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 @io.nil?
163
+ return if @pid.nil?
164
164
  wait(Process::WNOHANG|Process::WUNTRACED)
165
165
  Process.kill(0, @pid)
166
166
  true
@@ -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
- piper.instance_variable_set(:@child_pid, pid)
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
 
@@ -209,7 +209,7 @@ class Servolux::Prefork
209
209
  # @return [Prefork] self
210
210
  #
211
211
  def reap
212
- @workers.each { |worker| worker.alive? }
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::WNOHANG|Process::WUNTRACED)
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
  #
@@ -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
- Thread.new do
268
- begin
269
- self.send(method)
270
- rescue StandardError => err
271
- logger.error "Exception in signal handler: #{method}"
272
- logger.error err
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
@@ -1,5 +1,5 @@
1
1
  module Servolux
2
- VERSION = "0.12.0".freeze
2
+ VERSION = "0.13.0".freeze
3
3
 
4
4
  # Returns the version string for the library.
5
5
  def self.version
@@ -2,7 +2,7 @@
2
2
 
3
3
  gem list -i bones >/dev/null 2>&1
4
4
  rc=$?
5
- if [[ $rc != 0 ]]; then
5
+ if [ "$rc" != "0" ]; then
6
6
  gem install bones
7
7
  fi
8
8
 
@@ -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
- sleep 0.1 until ary.all? { |w| w.alive? }
69
- sleep 0.1 until worker_count >= 1
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
- sleep 0.250 until ary.all? { |w| w.alive? }
81
- sleep 0.250 until worker_count >= 8
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
- sleep 0.250 until ary.all? { |w| w.alive? }
95
- sleep 0.250 until worker_count >= 3
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
- sleep 0.250 until Dir.glob(@glob).length == 0
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
- sleep 0.250 until ary.all? { |w| w.alive? }
113
- sleep 0.250 until worker_count >= 2
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
- @prefork.reap until !alive? pid
118
- sleep 0.250 until ary.all? { |w| w.alive? }
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
- sleep 0.250 until ary.all? { |w| w.alive? }
128
- sleep 0.250 until worker_count >= 2
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
- @prefork.reap until !alive? pid
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
- sleep 0.250 until ary.all? { |w| w.alive? }
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
- sleep 0.250 until ary.all? { |w| w.alive? }
146
- sleep 0.250 until worker_count >= 2
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
- sleep 0.250 until worker_count >= 4
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
- sleep 0.250 until ary.all? { |w| w.alive? }
159
- sleep 0.250 until worker_count >= 2
164
+ wait_until { ary.all? { |w| w.alive? } }
165
+ wait_until { worker_count >= 2 }
160
166
 
161
167
  @prefork.add_workers( 2 )
162
- sleep 0.250 until worker_count >= 3
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
- sleep 0.250 until ary.all? { |w| w.alive? }
171
- sleep 0.250 until worker_count >= 2
176
+ wait_until { ary.all? { |w| w.alive? } }
177
+ wait_until { worker_count >= 2 }
172
178
 
173
179
  @prefork.add_workers( 2 )
174
- sleep 0.250 until worker_count >= 3
180
+ wait_until { worker_count >= 3 }
175
181
  expect(workers.size).to eq(4)
176
182
 
177
183
  workers[0].stop
178
- sleep 0.250 while workers[0].alive?
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
- sleep 0.250 until ary.all? { |w| w.alive? }
189
- sleep 0.250 until worker_count >= 1
194
+ wait_until { ary.all? { |w| w.alive? } }
195
+ wait_until { worker_count >= 1 }
190
196
 
191
197
  @prefork.ensure_worker_pool_size
192
- sleep 0.250 until worker_count >= 3
198
+ wait_until { worker_count >= 3 }
193
199
  expect(workers.size).to eq(3)
194
200
  end
195
201
  end
@@ -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 or yield
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(@log_output.readline.chomp).to eq(%q(DEBUG Servolux : Writing pid file "./test_server.pid"))
46
- expect(@log_output.readline.chomp).to eq(%q(DEBUG Servolux : Starting))
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(@log_output.readline.chomp).to eq(%q(DEBUG Servolux : Writing pid file "./test_server.pid"))
64
- expect(@log_output.readline.chomp).to eq(%q(DEBUG Servolux : Starting))
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
- `kill -SIGINT #{$$}`
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
- @log_output.readline
95
- expect(@log_output.readline.strip).to eq('DEBUG Servolux : Starting')
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 = @log_output.readline }
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 = @log_output.readline }
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 = @log_output.readline }
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
- @log_output.readline
128
- expect(@log_output.readline.strip).to eq('DEBUG Servolux : Starting')
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 = @log_output.readline }
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 = @log_output.readline }
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.12.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: 2015-06-08 00:00:00.000000000 Z
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.3
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.3
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.2.3
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