serverengine 1.5.3 → 1.5.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Changelog +6 -0
- data/lib/serverengine/daemon.rb +2 -2
- data/lib/serverengine/signal_thread.rb +27 -52
- data/lib/serverengine/version.rb +1 -1
- data/spec/blocking_flag_spec.rb +1 -0
- data/spec/server_worker_context.rb +24 -13
- data/spec/signal_thread_spec.rb +3 -2
- data/spec/supervisor_spec.rb +2 -0
- metadata +2 -2
data/Changelog
CHANGED
data/lib/serverengine/daemon.rb
CHANGED
@@ -43,7 +43,7 @@ module ServerEngine
|
|
43
43
|
|
44
44
|
old = @handlers[sig]
|
45
45
|
if block
|
46
|
-
Kernel.trap(sig) {
|
46
|
+
Kernel.trap(sig) { signal_handler_main(sig) }
|
47
47
|
@handlers[sig] = block
|
48
48
|
else
|
49
49
|
Kernel.trap(sig, command)
|
@@ -59,83 +59,58 @@ module ServerEngine
|
|
59
59
|
|
60
60
|
def stop
|
61
61
|
@mutex.synchronize do
|
62
|
-
## synchronized state 1
|
63
62
|
@finished = true
|
64
63
|
@cond.broadcast
|
65
|
-
## synchronized state 2
|
66
64
|
end
|
67
65
|
self
|
68
66
|
end
|
69
67
|
|
70
68
|
private
|
71
69
|
|
72
|
-
def
|
73
|
-
|
70
|
+
def signal_handler_main(sig)
|
71
|
+
# here always creates new thread to avoid
|
72
|
+
# complicated race conditin in signal handlers
|
73
|
+
Thread.new do
|
74
|
+
begin
|
75
|
+
enqueue(sig)
|
76
|
+
rescue => e
|
77
|
+
ServerEngine.dump_uncaught_error(e)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
74
81
|
|
82
|
+
def main
|
75
83
|
until @finished
|
76
|
-
|
84
|
+
sig = nil
|
77
85
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
@cond.wait(@mutex, 1)
|
82
|
-
next
|
83
|
-
end
|
86
|
+
@mutex.synchronize do
|
87
|
+
while true
|
88
|
+
return if @finished
|
84
89
|
|
85
|
-
|
90
|
+
sig = @queue.shift
|
91
|
+
break if sig
|
92
|
+
|
93
|
+
@cond.wait(@mutex, 1)
|
94
|
+
end
|
95
|
+
end
|
86
96
|
|
87
|
-
@mutex.unlock
|
88
97
|
begin
|
89
98
|
@handlers[sig].call(sig)
|
90
|
-
rescue
|
91
|
-
ServerEngine.dump_uncaught_error(
|
92
|
-
ensure
|
93
|
-
@mutex.lock
|
99
|
+
rescue => e
|
100
|
+
ServerEngine.dump_uncaught_error(e)
|
94
101
|
end
|
95
102
|
end
|
96
103
|
|
97
|
-
## synchronized state 6
|
98
104
|
nil
|
99
105
|
|
100
106
|
ensure
|
101
|
-
@mutex.unlock
|
102
107
|
@finished = false
|
103
108
|
end
|
104
109
|
|
105
110
|
def enqueue(sig)
|
106
|
-
@
|
107
|
-
|
108
|
-
unless @mutex.try_lock
|
109
|
-
#
|
110
|
-
# here couldn't acquire @mutex.
|
111
|
-
#
|
112
|
-
# A) a thread is in synchronized state 1 or 2.
|
113
|
-
# In this case, here doesn't have to broadcast because the thread will/did broadcast.
|
114
|
-
#
|
115
|
-
# B) `self` thread is in synchronized state 3
|
116
|
-
# In this case, here doesn't have to broadcast because the `self` thread will
|
117
|
-
# take a task from the queue soon.
|
118
|
-
#
|
119
|
-
# C) `self` thread is in synchronized state 4
|
120
|
-
# In this case, here needs to broadcast but doesn't broadcast. Thus it causes
|
121
|
-
# blocking upto 1 second :(
|
122
|
-
#
|
123
|
-
# D) `self` thread is in synchronized state 5
|
124
|
-
# In this case, here doesn't have to broadcast because the `self` thread will
|
125
|
-
# change to synchronized state 3 or 6 soon.
|
126
|
-
#
|
127
|
-
# E) the main thread (the only thread which calls this method) is in synchronized
|
128
|
-
# state 7. In this case, here doesn't have to broadcast.
|
129
|
-
#
|
130
|
-
return
|
131
|
-
end
|
132
|
-
|
133
|
-
## synchronized state 7
|
134
|
-
|
135
|
-
begin
|
111
|
+
@mutex.synchronize do
|
112
|
+
@queue << sig
|
136
113
|
@cond.broadcast
|
137
|
-
ensure
|
138
|
-
@mutex.unlock
|
139
114
|
end
|
140
115
|
end
|
141
116
|
|
data/lib/serverengine/version.rb
CHANGED
data/spec/blocking_flag_spec.rb
CHANGED
@@ -1,32 +1,39 @@
|
|
1
1
|
|
2
|
-
require '
|
2
|
+
require 'thread'
|
3
|
+
require 'yaml'
|
3
4
|
|
4
5
|
def reset_test_state
|
5
6
|
FileUtils.mkdir_p 'tmp'
|
6
|
-
FileUtils.rm_f 'tmp/state.
|
7
|
-
FileUtils.touch 'tmp/state.
|
7
|
+
FileUtils.rm_f 'tmp/state.yml'
|
8
|
+
FileUtils.touch 'tmp/state.yml'
|
9
|
+
$state_file_mutex = Mutex.new
|
8
10
|
end
|
9
11
|
|
10
12
|
def incr_test_state(key)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
File.open('tmp/state.yml', 'r+') do |f|
|
14
|
+
f.flock(File::LOCK_EX)
|
15
|
+
|
16
|
+
$state_file_mutex.synchronize do
|
17
|
+
data = YAML.load(f.read) || {} rescue {}
|
18
|
+
data[key] ||= 0
|
19
|
+
data[key] += 1
|
20
|
+
|
21
|
+
f.pos = 0
|
22
|
+
f.write YAML.dump(data)
|
23
|
+
end
|
15
24
|
end
|
16
25
|
end
|
17
26
|
|
18
27
|
def test_state(key)
|
19
|
-
|
20
|
-
|
21
|
-
return ps[key] || 0
|
22
|
-
end
|
28
|
+
data = YAML.load_file('tmp/state.yml') || {} rescue {}
|
29
|
+
return data[key] || 0
|
23
30
|
end
|
24
31
|
|
25
32
|
shared_context 'test server and worker' do
|
26
33
|
before { reset_test_state }
|
27
34
|
|
28
35
|
def wait_for_fork
|
29
|
-
sleep 0.
|
36
|
+
sleep 0.8
|
30
37
|
end
|
31
38
|
|
32
39
|
def wait_for_stop
|
@@ -97,7 +104,11 @@ shared_context 'test server and worker' do
|
|
97
104
|
|
98
105
|
def run
|
99
106
|
incr_test_state :worker_run
|
100
|
-
|
107
|
+
5.times do
|
108
|
+
# repeats 5 times because signal handlers
|
109
|
+
# interrupts wait
|
110
|
+
@stop_flag.wait(5.0)
|
111
|
+
end
|
101
112
|
@stop_flag.reset!
|
102
113
|
end
|
103
114
|
|
data/spec/signal_thread_spec.rb
CHANGED
@@ -14,6 +14,7 @@ describe ServerEngine::SignalThread do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
Process.kill('CONT', Process.pid)
|
17
|
+
sleep 0.5
|
17
18
|
|
18
19
|
t.stop.join
|
19
20
|
|
@@ -43,8 +44,7 @@ describe ServerEngine::SignalThread do
|
|
43
44
|
end
|
44
45
|
|
45
46
|
Process.kill('QUIT', Process.pid)
|
46
|
-
|
47
|
-
sleep 1
|
47
|
+
sleep 0.5
|
48
48
|
|
49
49
|
n.should == 3
|
50
50
|
end
|
@@ -57,6 +57,7 @@ describe ServerEngine::SignalThread do
|
|
57
57
|
end
|
58
58
|
|
59
59
|
Process.kill('QUIT', Process.pid)
|
60
|
+
sleep 0.5
|
60
61
|
|
61
62
|
t.join
|
62
63
|
end
|
data/spec/supervisor_spec.rb
CHANGED
@@ -53,6 +53,7 @@ describe ServerEngine::Supervisor do
|
|
53
53
|
wait_for_fork
|
54
54
|
|
55
55
|
sv.restart(true)
|
56
|
+
wait_for_stop
|
56
57
|
|
57
58
|
ensure
|
58
59
|
sv.stop(true)
|
@@ -74,6 +75,7 @@ describe ServerEngine::Supervisor do
|
|
74
75
|
wait_for_fork
|
75
76
|
|
76
77
|
sv.restart(false)
|
78
|
+
wait_for_stop
|
77
79
|
|
78
80
|
ensure
|
79
81
|
sv.stop(true)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: serverengine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-09-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sigdump
|