serverengine 1.5.3 → 1.5.4
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/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
|