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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/Changelog +11 -0
  4. data/README.md +31 -3
  5. data/Rakefile +16 -3
  6. data/appveyor.yml +11 -5
  7. data/examples/server.rb +138 -0
  8. data/examples/spawn_worker_script.rb +38 -0
  9. data/lib/serverengine/blocking_flag.rb +2 -3
  10. data/lib/serverengine/command_sender.rb +89 -0
  11. data/lib/serverengine/config_loader.rb +2 -0
  12. data/lib/serverengine/daemon.rb +114 -86
  13. data/lib/serverengine/daemon_logger.rb +3 -139
  14. data/lib/serverengine/embedded_server.rb +2 -0
  15. data/lib/serverengine/multi_process_server.rb +28 -7
  16. data/lib/serverengine/multi_spawn_server.rb +17 -18
  17. data/lib/serverengine/multi_thread_server.rb +6 -0
  18. data/lib/serverengine/multi_worker_server.rb +14 -0
  19. data/lib/serverengine/privilege.rb +57 -0
  20. data/lib/serverengine/process_manager.rb +66 -48
  21. data/lib/serverengine/server.rb +45 -11
  22. data/lib/serverengine/signal_thread.rb +0 -2
  23. data/lib/serverengine/signals.rb +31 -0
  24. data/lib/serverengine/socket_manager.rb +3 -5
  25. data/lib/serverengine/socket_manager_unix.rb +1 -0
  26. data/lib/serverengine/socket_manager_win.rb +4 -2
  27. data/lib/serverengine/supervisor.rb +105 -25
  28. data/lib/serverengine/utils.rb +23 -0
  29. data/lib/serverengine/version.rb +1 -1
  30. data/lib/serverengine/worker.rb +10 -7
  31. data/lib/serverengine.rb +9 -27
  32. data/serverengine.gemspec +12 -1
  33. data/spec/daemon_logger_spec.rb +17 -12
  34. data/spec/daemon_spec.rb +147 -24
  35. data/spec/multi_process_server_spec.rb +59 -7
  36. data/spec/server_worker_context.rb +104 -0
  37. data/spec/signal_thread_spec.rb +61 -56
  38. data/spec/supervisor_spec.rb +113 -99
  39. metadata +40 -6
@@ -6,84 +6,89 @@ describe ServerEngine::SignalThread do
6
6
  t.join
7
7
  end
8
8
 
9
- it 'call handler' do
10
- n = 0
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('QUIT', 'SIG_IGN')
14
+ st.trap('CONT') { n += 1 }
31
15
  end
32
16
 
33
- Process.kill('QUIT', Process.pid)
17
+ Process.kill('CONT', Process.pid)
18
+ sleep 0.5
34
19
 
35
20
  t.stop.join
36
- end
37
- end
38
21
 
39
- it 'signal in handler' do
40
- n = 0
22
+ n.should == 1
23
+ end
41
24
 
42
- SignalThread.new do |st|
43
- st.trap('QUIT') do
44
- if n < 3
45
- Process.kill('QUIT', Process.pid)
46
- n += 1
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
- Process.kill('QUIT', Process.pid)
52
- sleep 0.5
40
+ it 'signal in handler' do
41
+ n = 0
53
42
 
54
- n.should == 3
55
- end
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
- it 'stop in handler' do
58
- t = SignalThread.new do |st|
59
- st.trap('QUIT') { st.stop }
60
- end
52
+ Process.kill('QUIT', Process.pid)
53
+ sleep 0.5
61
54
 
62
- Process.kill('QUIT', Process.pid)
63
- sleep 0.5
55
+ n.should == 3
56
+ end
64
57
 
65
- t.join
66
- end
58
+ it 'stop in handler' do
59
+ t = SignalThread.new do |st|
60
+ st.trap('QUIT') { st.stop }
61
+ end
67
62
 
68
- it 'should not deadlock' do
69
- n = 0
63
+ Process.kill('QUIT', Process.pid)
64
+ sleep 0.5
70
65
 
71
- SignalThread.new do |st|
72
- st.trap('CONT') { n += 1 }
66
+ t.join
73
67
  end
74
68
 
75
- (1..10).map {
76
- Thread.new do
77
- 10.times {
78
- Process.kill('CONT', Process.pid)
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
- # result won't be 100 because of kernel limitation
86
- n.should > 0
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
 
@@ -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
- sv = Supervisor.new(TestServer, TestWorker, config)
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
- it 'start and graceful stop' do
70
- sv, t = start_supervisor
75
+ ['signal', 'pipe'].each do |sender|
76
+ context "when using #{sender} as command_sender" do
71
77
 
72
- begin
73
- wait_for_fork
78
+ it 'start and graceful stop' do
79
+ pending 'not supported on Windows' if ServerEngine.windows? && sender == 'signal'
74
80
 
75
- test_state(:server_before_run).should == 1
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
- test_state(:server_stop).should == 1
83
- test_state(:server_stop_graceful).should == 1
84
- test_state(:server_restart).should == 0
83
+ begin
84
+ wait_for_fork
85
85
 
86
- test_state(:server_after_run).should == 1
87
- test_state(:server_after_start).should == 1
88
- end
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
- it 'immediate stop' do
91
- sv, t = start_supervisor
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
- begin
94
- wait_for_fork
95
- ensure
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
- test_state(:server_stop).should == 1
101
- test_state(:server_stop_immediate).should == 1
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
- it 'graceful restart' do
107
- sv, t = start_supervisor
104
+ sv, t = start_supervisor(command_sender: sender)
108
105
 
109
- begin
110
- wait_for_fork
106
+ begin
107
+ wait_for_fork
108
+ ensure
109
+ sv.stop(false)
110
+ t.join
111
+ end
111
112
 
112
- sv.restart(true)
113
- wait_for_stop
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
- ensure
116
- sv.stop(true)
117
- t.join
118
- end
119
+ it 'graceful restart' do
120
+ pending 'not supported on Windows' if ServerEngine.windows? && sender == 'signal'
119
121
 
120
- test_state(:server_stop).should == 1
121
- test_state(:server_restart_graceful).should == 1
122
+ sv, t = start_supervisor(command_sender: sender)
122
123
 
123
- test_state(:server_before_run).should == 1
124
- test_state(:server_after_run).should == 1
125
- test_state(:server_after_start).should == 1
126
- end
124
+ begin
125
+ wait_for_fork
127
126
 
128
- it 'immediate restart' do
129
- sv, t = start_supervisor
127
+ sv.restart(true)
128
+ wait_for_stop
130
129
 
131
- begin
132
- wait_for_fork
130
+ ensure
131
+ sv.stop(true)
132
+ t.join
133
+ end
133
134
 
134
- sv.restart(false)
135
- wait_for_stop
135
+ test_state(:server_stop).should == 1
136
+ test_state(:server_restart_graceful).should == 1
136
137
 
137
- ensure
138
- sv.stop(true)
139
- t.join
140
- end
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
- test_state(:server_stop).should == 1
143
- test_state(:server_restart_immediate).should == 1
143
+ it 'immediate restart' do
144
+ pending 'not supported on Windows' if ServerEngine.windows? && sender == 'signal'
144
145
 
145
- test_state(:server_before_run).should == 1
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
- it 'reload' do
151
- sv, t = start_supervisor
148
+ begin
149
+ wait_for_fork
152
150
 
153
- begin
154
- wait_for_fork
151
+ sv.restart(false)
152
+ wait_for_stop
155
153
 
156
- sv.reload
154
+ ensure
155
+ sv.stop(true)
156
+ t.join
157
+ end
157
158
 
158
- ensure
159
- sv.stop(true)
160
- t.join
161
- end
159
+ test_state(:server_stop).should == 1
160
+ test_state(:server_restart_immediate).should == 1
162
161
 
163
- test_state(:server_stop).should == 1
164
- test_state(:server_reload).should == 1
165
- end
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
- # TODO detach
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: 1.6.4
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-05-19 00:00:00.000000000 Z
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.9.3
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: '0'
153
+ version: 1.3.1
121
154
  requirements: []
122
155
  rubyforge_project:
123
- rubygems_version: 2.4.5
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