serverengine 1.6.4 → 2.0.0pre1
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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Changelog +11 -0
- data/README.md +31 -3
- data/Rakefile +16 -3
- data/appveyor.yml +11 -5
- data/examples/server.rb +138 -0
- data/examples/spawn_worker_script.rb +38 -0
- data/lib/serverengine/blocking_flag.rb +2 -3
- data/lib/serverengine/command_sender.rb +89 -0
- data/lib/serverengine/config_loader.rb +2 -0
- data/lib/serverengine/daemon.rb +114 -86
- data/lib/serverengine/daemon_logger.rb +3 -139
- data/lib/serverengine/embedded_server.rb +2 -0
- data/lib/serverengine/multi_process_server.rb +28 -7
- data/lib/serverengine/multi_spawn_server.rb +17 -18
- data/lib/serverengine/multi_thread_server.rb +6 -0
- data/lib/serverengine/multi_worker_server.rb +14 -0
- data/lib/serverengine/privilege.rb +57 -0
- data/lib/serverengine/process_manager.rb +66 -48
- data/lib/serverengine/server.rb +45 -11
- data/lib/serverengine/signal_thread.rb +0 -2
- data/lib/serverengine/signals.rb +31 -0
- data/lib/serverengine/socket_manager.rb +3 -5
- data/lib/serverengine/socket_manager_unix.rb +1 -0
- data/lib/serverengine/socket_manager_win.rb +4 -2
- data/lib/serverengine/supervisor.rb +105 -25
- data/lib/serverengine/utils.rb +23 -0
- data/lib/serverengine/version.rb +1 -1
- data/lib/serverengine/worker.rb +10 -7
- data/lib/serverengine.rb +9 -27
- data/serverengine.gemspec +12 -1
- data/spec/daemon_logger_spec.rb +17 -12
- data/spec/daemon_spec.rb +147 -24
- data/spec/multi_process_server_spec.rb +59 -7
- data/spec/server_worker_context.rb +104 -0
- data/spec/signal_thread_spec.rb +61 -56
- data/spec/supervisor_spec.rb +113 -99
- metadata +40 -6
data/spec/signal_thread_spec.rb
CHANGED
@@ -6,84 +6,89 @@ describe ServerEngine::SignalThread do
|
|
6
6
|
t.join
|
7
7
|
end
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
unless ServerEngine.windows?
|
10
|
+
it 'call handler' do
|
11
|
+
n = 0
|
11
12
|
|
12
|
-
t = SignalThread.new do |st|
|
13
|
-
st.trap('CONT') { n += 1 }
|
14
|
-
end
|
15
|
-
|
16
|
-
Process.kill('CONT', Process.pid)
|
17
|
-
sleep 0.5
|
18
|
-
|
19
|
-
t.stop.join
|
20
|
-
|
21
|
-
n.should == 1
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'SIG_IGN' do
|
25
|
-
# IGNORE signal handler has possible race condition in Ruby 2.1
|
26
|
-
# https://bugs.ruby-lang.org/issues/9835
|
27
|
-
# That's why ignore this test in Ruby2.1
|
28
|
-
if RUBY_VERSION >= '2.2'
|
29
13
|
t = SignalThread.new do |st|
|
30
|
-
st.trap('
|
14
|
+
st.trap('CONT') { n += 1 }
|
31
15
|
end
|
32
16
|
|
33
|
-
Process.kill('
|
17
|
+
Process.kill('CONT', Process.pid)
|
18
|
+
sleep 0.5
|
34
19
|
|
35
20
|
t.stop.join
|
36
|
-
end
|
37
|
-
end
|
38
21
|
|
39
|
-
|
40
|
-
|
22
|
+
n.should == 1
|
23
|
+
end
|
41
24
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
25
|
+
it 'SIG_IGN' do
|
26
|
+
# IGNORE signal handler has possible race condition in Ruby 2.1
|
27
|
+
# https://bugs.ruby-lang.org/issues/9835
|
28
|
+
# That's why ignore this test in Ruby2.1
|
29
|
+
if RUBY_VERSION >= '2.2'
|
30
|
+
t = SignalThread.new do |st|
|
31
|
+
st.trap('QUIT', 'SIG_IGN')
|
47
32
|
end
|
33
|
+
|
34
|
+
Process.kill('QUIT', Process.pid)
|
35
|
+
|
36
|
+
t.stop.join
|
48
37
|
end
|
49
38
|
end
|
50
39
|
|
51
|
-
|
52
|
-
|
40
|
+
it 'signal in handler' do
|
41
|
+
n = 0
|
53
42
|
|
54
|
-
|
55
|
-
|
43
|
+
SignalThread.new do |st|
|
44
|
+
st.trap('QUIT') do
|
45
|
+
if n < 3
|
46
|
+
Process.kill('QUIT', Process.pid)
|
47
|
+
n += 1
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
56
51
|
|
57
|
-
|
58
|
-
|
59
|
-
st.trap('QUIT') { st.stop }
|
60
|
-
end
|
52
|
+
Process.kill('QUIT', Process.pid)
|
53
|
+
sleep 0.5
|
61
54
|
|
62
|
-
|
63
|
-
|
55
|
+
n.should == 3
|
56
|
+
end
|
64
57
|
|
65
|
-
|
66
|
-
|
58
|
+
it 'stop in handler' do
|
59
|
+
t = SignalThread.new do |st|
|
60
|
+
st.trap('QUIT') { st.stop }
|
61
|
+
end
|
67
62
|
|
68
|
-
|
69
|
-
|
63
|
+
Process.kill('QUIT', Process.pid)
|
64
|
+
sleep 0.5
|
70
65
|
|
71
|
-
|
72
|
-
st.trap('CONT') { n += 1 }
|
66
|
+
t.join
|
73
67
|
end
|
74
68
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
}
|
69
|
+
it 'should not deadlock' do
|
70
|
+
n = 0
|
71
|
+
|
72
|
+
SignalThread.new do |st|
|
73
|
+
st.trap('CONT') { n += 1 }
|
80
74
|
end
|
81
|
-
}.each { |t|
|
82
|
-
t.join
|
83
|
-
}
|
84
75
|
|
85
|
-
|
86
|
-
|
76
|
+
(1..10).map {
|
77
|
+
Thread.new do
|
78
|
+
10.times {
|
79
|
+
Process.kill('CONT', Process.pid)
|
80
|
+
}
|
81
|
+
end
|
82
|
+
}.each { |t|
|
83
|
+
t.join
|
84
|
+
}
|
85
|
+
|
86
|
+
# give chance to run the signal thread
|
87
|
+
sleep 0.1
|
88
|
+
|
89
|
+
# result won't be 100 because of kernel limitation
|
90
|
+
n.should > 0
|
91
|
+
end
|
87
92
|
end
|
88
93
|
end
|
89
94
|
|
data/spec/supervisor_spec.rb
CHANGED
@@ -2,14 +2,20 @@
|
|
2
2
|
describe ServerEngine::Supervisor do
|
3
3
|
include_context 'test server and worker'
|
4
4
|
|
5
|
-
def start_supervisor(config
|
6
|
-
|
5
|
+
def start_supervisor(worker = nil, **config)
|
6
|
+
if ServerEngine.windows?
|
7
|
+
config[:windows_daemon_cmdline] = windows_supervisor_cmdline(nil, worker, config)
|
8
|
+
end
|
9
|
+
sv = Supervisor.new(TestServer, worker || TestWorker, config)
|
7
10
|
t = Thread.new { sv.main }
|
8
11
|
|
9
12
|
return sv, t
|
10
13
|
end
|
11
14
|
|
12
|
-
def start_daemon(config
|
15
|
+
def start_daemon(**config)
|
16
|
+
if ServerEngine.windows?
|
17
|
+
config[:windows_daemon_cmdline] = windows_daemon_cmdline
|
18
|
+
end
|
13
19
|
daemon = Daemon.new(nil, TestWorker, config)
|
14
20
|
t = Thread.new { daemon.main }
|
15
21
|
|
@@ -66,105 +72,135 @@ describe ServerEngine::Supervisor do
|
|
66
72
|
end
|
67
73
|
end
|
68
74
|
|
69
|
-
|
70
|
-
|
75
|
+
['signal', 'pipe'].each do |sender|
|
76
|
+
context "when using #{sender} as command_sender" do
|
71
77
|
|
72
|
-
|
73
|
-
|
78
|
+
it 'start and graceful stop' do
|
79
|
+
pending 'not supported on Windows' if ServerEngine.windows? && sender == 'signal'
|
74
80
|
|
75
|
-
|
76
|
-
test_state(:server_after_start).should == 1 # parent
|
77
|
-
ensure
|
78
|
-
sv.stop(true)
|
79
|
-
t.join
|
80
|
-
end
|
81
|
+
sv, t = start_supervisor(command_sender: sender)
|
81
82
|
|
82
|
-
|
83
|
-
|
84
|
-
test_state(:server_restart).should == 0
|
83
|
+
begin
|
84
|
+
wait_for_fork
|
85
85
|
|
86
|
-
|
87
|
-
|
88
|
-
|
86
|
+
test_state(:server_before_run).should == 1
|
87
|
+
test_state(:server_after_start).should == 1 # parent
|
88
|
+
ensure
|
89
|
+
sv.stop(true)
|
90
|
+
t.join
|
91
|
+
end
|
89
92
|
|
90
|
-
|
91
|
-
|
93
|
+
test_state(:server_stop).should == 1
|
94
|
+
test_state(:server_stop_graceful).should == 1
|
95
|
+
test_state(:server_restart).should == 0
|
92
96
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
sv.stop(false)
|
97
|
-
t.join
|
98
|
-
end
|
97
|
+
test_state(:server_after_run).should == 1
|
98
|
+
test_state(:server_after_start).should == 1
|
99
|
+
end
|
99
100
|
|
100
|
-
|
101
|
-
|
102
|
-
test_state(:server_after_run).should == 1
|
103
|
-
test_state(:server_after_start).should == 1
|
104
|
-
end
|
101
|
+
it 'immediate stop' do
|
102
|
+
pending 'not supported on Windows' if ServerEngine.windows? && sender == 'signal'
|
105
103
|
|
106
|
-
|
107
|
-
sv, t = start_supervisor
|
104
|
+
sv, t = start_supervisor(command_sender: sender)
|
108
105
|
|
109
|
-
|
110
|
-
|
106
|
+
begin
|
107
|
+
wait_for_fork
|
108
|
+
ensure
|
109
|
+
sv.stop(false)
|
110
|
+
t.join
|
111
|
+
end
|
111
112
|
|
112
|
-
|
113
|
-
|
113
|
+
test_state(:server_stop).should == 1
|
114
|
+
test_state(:server_stop_immediate).should == 1
|
115
|
+
test_state(:server_after_run).should == 1
|
116
|
+
test_state(:server_after_start).should == 1
|
117
|
+
end
|
114
118
|
|
115
|
-
|
116
|
-
|
117
|
-
t.join
|
118
|
-
end
|
119
|
+
it 'graceful restart' do
|
120
|
+
pending 'not supported on Windows' if ServerEngine.windows? && sender == 'signal'
|
119
121
|
|
120
|
-
|
121
|
-
test_state(:server_restart_graceful).should == 1
|
122
|
+
sv, t = start_supervisor(command_sender: sender)
|
122
123
|
|
123
|
-
|
124
|
-
|
125
|
-
test_state(:server_after_start).should == 1
|
126
|
-
end
|
124
|
+
begin
|
125
|
+
wait_for_fork
|
127
126
|
|
128
|
-
|
129
|
-
|
127
|
+
sv.restart(true)
|
128
|
+
wait_for_stop
|
130
129
|
|
131
|
-
|
132
|
-
|
130
|
+
ensure
|
131
|
+
sv.stop(true)
|
132
|
+
t.join
|
133
|
+
end
|
133
134
|
|
134
|
-
|
135
|
-
|
135
|
+
test_state(:server_stop).should == 1
|
136
|
+
test_state(:server_restart_graceful).should == 1
|
136
137
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
138
|
+
test_state(:server_before_run).should == 1
|
139
|
+
test_state(:server_after_run).should == 1
|
140
|
+
test_state(:server_after_start).should == 1
|
141
|
+
end
|
141
142
|
|
142
|
-
|
143
|
-
|
143
|
+
it 'immediate restart' do
|
144
|
+
pending 'not supported on Windows' if ServerEngine.windows? && sender == 'signal'
|
144
145
|
|
145
|
-
|
146
|
-
test_state(:server_after_run).should == 1
|
147
|
-
test_state(:server_after_start).should == 1
|
148
|
-
end
|
146
|
+
sv, t = start_supervisor(command_sender: sender)
|
149
147
|
|
150
|
-
|
151
|
-
|
148
|
+
begin
|
149
|
+
wait_for_fork
|
152
150
|
|
153
|
-
|
154
|
-
|
151
|
+
sv.restart(false)
|
152
|
+
wait_for_stop
|
155
153
|
|
156
|
-
|
154
|
+
ensure
|
155
|
+
sv.stop(true)
|
156
|
+
t.join
|
157
|
+
end
|
157
158
|
|
158
|
-
|
159
|
-
|
160
|
-
t.join
|
161
|
-
end
|
159
|
+
test_state(:server_stop).should == 1
|
160
|
+
test_state(:server_restart_immediate).should == 1
|
162
161
|
|
163
|
-
|
164
|
-
|
165
|
-
|
162
|
+
test_state(:server_before_run).should == 1
|
163
|
+
test_state(:server_after_run).should == 1
|
164
|
+
test_state(:server_after_start).should == 1
|
165
|
+
end
|
166
166
|
|
167
|
-
|
167
|
+
it 'reload' do
|
168
|
+
pending 'not supported on Windows' if ServerEngine.windows? && sender == 'signal'
|
169
|
+
|
170
|
+
sv, t = start_supervisor(command_sender: sender)
|
171
|
+
|
172
|
+
begin
|
173
|
+
wait_for_fork
|
174
|
+
|
175
|
+
sv.reload
|
176
|
+
|
177
|
+
ensure
|
178
|
+
sv.stop(true)
|
179
|
+
t.join
|
180
|
+
end
|
181
|
+
|
182
|
+
test_state(:server_stop).should == 1
|
183
|
+
test_state(:server_reload).should == 1
|
184
|
+
end
|
185
|
+
|
186
|
+
# TODO detach
|
187
|
+
|
188
|
+
it 'auto restart in limited ratio' do
|
189
|
+
pending 'not supported on Windows' if ServerEngine.windows? && sender == 'signal'
|
190
|
+
|
191
|
+
sv, t = start_supervisor(RunErrorWorker, server_restart_wait: 1, command_sender: sender)
|
192
|
+
|
193
|
+
begin
|
194
|
+
sleep 2.2
|
195
|
+
ensure
|
196
|
+
sv.stop(true)
|
197
|
+
t.join
|
198
|
+
end
|
199
|
+
|
200
|
+
test_state(:worker_run).should == 3
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
168
204
|
|
169
205
|
module InitializeErrorServer
|
170
206
|
def initialize
|
@@ -176,26 +212,4 @@ describe ServerEngine::Supervisor do
|
|
176
212
|
sv = Supervisor.new(InitializeErrorServer, TestWorker)
|
177
213
|
lambda { sv.main }.should raise_error(StandardError)
|
178
214
|
end
|
179
|
-
|
180
|
-
module RunErrorWorker
|
181
|
-
def run
|
182
|
-
incr_test_state :worker_run
|
183
|
-
raise StandardError, "error test"
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
it 'auto restart in limited ratio' do
|
188
|
-
sv = Supervisor.new(TestServer, RunErrorWorker, server_restart_wait: 1)
|
189
|
-
t = Thread.new { sv.main }
|
190
|
-
|
191
|
-
begin
|
192
|
-
sleep 2.2
|
193
|
-
ensure
|
194
|
-
sv.stop(true)
|
195
|
-
t.join
|
196
|
-
end
|
197
|
-
|
198
|
-
test_state(:worker_run).should == 3
|
199
|
-
end
|
200
|
-
|
201
215
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: serverengine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0pre1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sigdump
|
@@ -52,6 +52,34 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 2.13.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake-compiler-dock
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.5.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.5.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake-compiler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.9.4
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.9.4
|
55
83
|
description: A framework to implement robust multiprocess servers like Unicorn
|
56
84
|
email:
|
57
85
|
- frsyuki@gmail.com
|
@@ -69,8 +97,11 @@ files:
|
|
69
97
|
- README.md
|
70
98
|
- Rakefile
|
71
99
|
- appveyor.yml
|
100
|
+
- examples/server.rb
|
101
|
+
- examples/spawn_worker_script.rb
|
72
102
|
- lib/serverengine.rb
|
73
103
|
- lib/serverengine/blocking_flag.rb
|
104
|
+
- lib/serverengine/command_sender.rb
|
74
105
|
- lib/serverengine/config_loader.rb
|
75
106
|
- lib/serverengine/daemon.rb
|
76
107
|
- lib/serverengine/daemon_logger.rb
|
@@ -79,9 +110,11 @@ files:
|
|
79
110
|
- lib/serverengine/multi_spawn_server.rb
|
80
111
|
- lib/serverengine/multi_thread_server.rb
|
81
112
|
- lib/serverengine/multi_worker_server.rb
|
113
|
+
- lib/serverengine/privilege.rb
|
82
114
|
- lib/serverengine/process_manager.rb
|
83
115
|
- lib/serverengine/server.rb
|
84
116
|
- lib/serverengine/signal_thread.rb
|
117
|
+
- lib/serverengine/signals.rb
|
85
118
|
- lib/serverengine/socket_manager.rb
|
86
119
|
- lib/serverengine/socket_manager_unix.rb
|
87
120
|
- lib/serverengine/socket_manager_win.rb
|
@@ -112,15 +145,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
112
145
|
requirements:
|
113
146
|
- - ">="
|
114
147
|
- !ruby/object:Gem::Version
|
115
|
-
version: 1.
|
148
|
+
version: 2.1.0
|
116
149
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
150
|
requirements:
|
118
|
-
- - "
|
151
|
+
- - ">"
|
119
152
|
- !ruby/object:Gem::Version
|
120
|
-
version:
|
153
|
+
version: 1.3.1
|
121
154
|
requirements: []
|
122
155
|
rubyforge_project:
|
123
|
-
rubygems_version: 2.
|
156
|
+
rubygems_version: 2.5.1
|
124
157
|
signing_key:
|
125
158
|
specification_version: 4
|
126
159
|
summary: ServerEngine - multiprocess server framework
|
@@ -134,3 +167,4 @@ test_files:
|
|
134
167
|
- spec/socket_manager_spec.rb
|
135
168
|
- spec/spec_helper.rb
|
136
169
|
- spec/supervisor_spec.rb
|
170
|
+
has_rdoc: false
|