serverengine 1.5.9 → 1.5.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NTE3MmE3Y2NkZWFlY2VmNmFmYjc4ZTk1MWEzYTIyMDQwYjNkZDY0Ng==
4
+ OWNiN2U5ZGRhMjk1NGI1ZDAxNmY3OWE5OTZkMWI0ZDI5Nzg3NDQzYw==
5
5
  data.tar.gz: !binary |-
6
- NGExMjkzMDk3MjdjZjA5ZDBmM2U0OGM0YWViZjgxZWRlNTVmMjg4Mg==
6
+ MTFlMzk4MjE1ZDdhZDdiMWRkNzg2YmY3M2MxMWU5MjY5OWU3ZTFkNw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MGY1NzhmY2Q2MDUzNzljNTVlYjcwNDQ3ZjBiYzQ3NWY4ZDA0MTQzYzViMTZi
10
- YTVmNzhlNzIzM2RhOWVkNDZkMzFkNmRhODc0ZTBmMzM1MThkM2VhNTg2NjY0
11
- YTZlMmFmNGJlMWMxMzBjNTRiNmU4MjQyZDdkY2U2NWUwZjdiNmM=
9
+ NGI0NjQyMWMxNTJmMzBlYTFhM2YwM2U2OGUwMWM4OGMzMzI4ODA4YmQ4ZGI3
10
+ ZjE5MTUzMzk2YTJkYWVjNTNkMzU0ZjkwZWU1ODY2M2VkNDUwZmM5ZjgxY2Qw
11
+ NWUyYzhmOWIyYTA0ZGQ3ZGUwYWMwYTNjODZlNzAyM2IwNWFlNDI=
12
12
  data.tar.gz: !binary |-
13
- OWJjOTljMWI5MTcxNzkwYzJjYmQxNWI3MTYwMTUzMTMxYzhhNjRlYzNlNjZl
14
- NDYzYjJiZWJkNTQ3NTM2NzYzZmM5ZjRhNzRjMTVmMDNiMjJjNzkyNTE5MjIx
15
- YmUwMjkwMDQ1ZTc0ZTQxMTY0NDBkYzY5NzE0MDc2ZDNmYWQ0NTk=
13
+ ZTRjMWQ0N2E4OTI5ZGUzOTZjYTU3ZTI5MzVmYzdiMjBjOGU5Yjg4NzBjOGE0
14
+ OGEwYzM2MDNiMTc5ZmE1NDQ4MjkwNGVhZjFiZDIxMzEzMTBiNzRkOWU0ZTM0
15
+ NmFkZWM1NTgyYjBmOGRhYzU1NmZjNzJiOGM5ZDYyNjBiYzQxNDI=
data/Changelog CHANGED
@@ -1,4 +1,13 @@
1
1
 
2
+ 2014-10-27 version 1.5.10:
3
+
4
+ * Added worker_type=spawn (experimental)
5
+ * Fixed Worker#config to reference Server#config so that Worker#reload reads
6
+ the new config reloaded by Server#reload (=ConfigLoader#reload_config) in
7
+ worker_type=thread and embedded
8
+ * Server#stop, #restart and #reload show a debug log message
9
+
10
+
2
11
  2014-07-24 version 1.5.9:
3
12
 
4
13
  * Fixed DaemonLogger#reoepen! on Ruby >= 2.1.0
data/README.md CHANGED
@@ -50,9 +50,9 @@ module MyWorker
50
50
  end
51
51
 
52
52
  se = ServerEngine.create(nil, MyWorker, {
53
- :daemonize => true,
54
- :log => 'myserver.log',
55
- :pid_path => 'myserver.pid',
53
+ daemonize: true,
54
+ log: 'myserver.log',
55
+ pid_path: 'myserver.pid',
56
56
  })
57
57
  se.run
58
58
  ```
@@ -66,11 +66,11 @@ Simply set **worker_type=process** or **worker_type=thread** parameter, and set
66
66
 
67
67
  ```ruby
68
68
  se = ServerEngine.create(nil, MyWorker, {
69
- :daemonize => true,
70
- :log => 'myserver.log',
71
- :pid_path => 'myserver.pid',
72
- :worker_type => 'process',
73
- :workers => 4,
69
+ daemonize: true,
70
+ log: 'myserver.log',
71
+ pid_path: 'myserver.pid',
72
+ worker_type: 'process',
73
+ workers: 4,
74
74
  })
75
75
  se.run
76
76
  ```
@@ -111,13 +111,54 @@ module MyWorker
111
111
  end
112
112
 
113
113
  se = ServerEngine.create(MyServer, MyWorker, {
114
- :daemonize => true,
115
- :log => 'myserver.log',
116
- :pid_path => 'myserver.pid',
117
- :worker_type => 'process',
118
- :workers => 4,
119
- :bind => '0.0.0.0',
120
- :port => 9071,
114
+ daemonize: true,
115
+ log: 'myserver.log',
116
+ pid_path: 'myserver.pid',
117
+ worker_type: 'process',
118
+ workers: 4,
119
+ bind: '0.0.0.0',
120
+ port: 9071,
121
+ })
122
+ se.run
123
+ ```
124
+
125
+
126
+ ### Multiprocess server on Windows and JRuby platform
127
+
128
+ Above **worker_type=process** depends on `fork` system call, which doesn't work on Windows or JRuby platform.
129
+ ServerEngine provides **worker_type=spawn** for those platforms (This is still EXPERIMENTAL). However, unfortunately, you need to implement different worker module because `worker_type=spawn` is not compatible with **worker_type=process** in terms of API.
130
+
131
+ What you need to implement at least to use worker_type=spawn is `spawn(process_manager)` method. You will call `process_manager.spawn` at the method, where `spawn` is same with `Process.spawn` excepting return value.
132
+
133
+ ```ruby
134
+ module MyWorker
135
+ def spawn(process_manager)
136
+ env = {
137
+ 'SERVER_ENGINE_CONFIG' => config.to_json
138
+ }
139
+ script = %[
140
+ require 'serverengine'
141
+ require 'json'
142
+
143
+ conf = JSON.parse(ENV['SERVER_ENGINE_CONFIG'], symbolize_names: true)
144
+ logger = ServerEngine::DaemonLogger.new(conf[:log] || STDOUT, conf)
145
+
146
+ @stop = false
147
+ trap(:SIGTERM) { @stop = true }
148
+ trap(:SIGINT) { @stop = true }
149
+
150
+ until @stop
151
+ logger.info 'Awesome work!'
152
+ sleep 1
153
+ end
154
+ ]
155
+ process_manager.spawn(env, "ruby", "-e", script)
156
+ end
157
+ end
158
+
159
+ se = ServerEngine.create(nil, MyWorker, {
160
+ worker_type: 'spawn',
161
+ log: 'myserver.log',
121
162
  })
122
163
  se.run
123
164
  ```
@@ -129,10 +170,10 @@ ServerEngine logger rotates logs by 1MB and keeps 5 generations by default.
129
170
 
130
171
  ```ruby
131
172
  se = ServerEngine.create(MyServer, MyWorker, {
132
- :log => 'myserver.log',
133
- :log_level => 'debug',
134
- :log_rotate_age => 5,
135
- :log_rotate_size => 1*1024*1024,
173
+ log: 'myserver.log',
174
+ log_level: 'debug',
175
+ log_rotate_age: 5,
176
+ log_rotate_size: 1*1024*1024,
136
177
  })
137
178
  se.run
138
179
  ```
@@ -154,9 +195,9 @@ Supervisor process runs as the parent process of the server process and monitor
154
195
 
155
196
  ```ruby
156
197
  se = ServerEngine.create(nil, MyWorker, {
157
- :daemonize => true,
158
- :pid_path => 'myserver.pid',
159
- :supervisor => true, # enable supervisor process
198
+ daemonize: true,
199
+ pid_path: 'myserver.pid',
200
+ supervisor: true, # enable supervisor process
160
201
  })
161
202
  se.run
162
203
  ```
@@ -229,8 +270,8 @@ end
229
270
 
230
271
  se = ServerEngine.create(nil, MyWorker) do
231
272
  YAML.load_file("config.yml").merge({
232
- :daemonize => true,
233
- :worker_type => 'process',
273
+ daemonize: true,
274
+ worker_type: 'process',
234
275
  })
235
276
  end
236
277
  se.run
@@ -264,8 +305,8 @@ end
264
305
 
265
306
  se = ServerEngine.create(nil, MyWorker) do
266
307
  YAML.load_file(config).merge({
267
- :daemonize => true,
268
- :worker_type => 'process'
308
+ daemonize: true,
309
+ worker_type: 'process'
269
310
  })
270
311
  end
271
312
  se.run
@@ -276,13 +317,16 @@ se.run
276
317
 
277
318
  ### Worker module
278
319
 
320
+ Available methods are different depending on `worker_type`.
321
+
279
322
  - interface
280
323
  - `initialize` is called in the parent process (or thread) in contrast to the other methods
281
- - `before_fork` is called before fork for each worker process (available only if `worker_type` is "process" or "thread")
282
- - `run` is the required method
283
- - `stop` is called when TERM signal is received
284
- - `reload` is called when USR2 signal is received
285
- - `after_start` is called after starting the worker process in the parent process (or thread) (available only if `worker_type` is "process" or "thread")
324
+ - `before_fork` is called before fork for each worker process [`worker_type` = "thread", "process"]
325
+ - `run` is the required method for `worker_type` = "embedded", "thread", "process"
326
+ - `spawn(process_manager)` is the required method for `worker_type` = "spawn". Should call `process_manager.spawn([env,] command... [,options])`.
327
+ - `stop` is called when TERM signal is received [`worker_type` = "embedded", "thread", "process"]
328
+ - `reload` is called when USR2 signal is received [`worker_type` = "embedded", "thread", "process"]
329
+ - `after_start` is called after starting the worker process in the parent process (or thread) [`worker_type` = "thread", "process", "spawn"]
286
330
  - api
287
331
  - `server` server instance
288
332
  - `config` configuration
@@ -296,7 +340,7 @@ se.run
296
340
  - `initialize` is called in the parent process in contrast to the other methods
297
341
  - `before_run` is called before starting workers
298
342
  - `after_run` is called before shutting down
299
- - `after_start` is called after starting the server process in the parent process (available only if `supervisor` parameter is true)
343
+ - `after_start` is called after starting the server process in the parent process (available if `supervisor` parameter is true)
300
344
  - hook points (call `super` in these methods)
301
345
  - `reload_config`
302
346
  - `stop(stop_graceful)`
@@ -312,7 +356,8 @@ ServerEngine supports 3 worker types:
312
356
 
313
357
  - **embedded**: uses a thread to run worker module (default). This type doesn't support immediate shutdown or immediate restart.
314
358
  - **thread**: uses threads to run worker modules. This type doesn't support immediate shutdown or immediate restart.
315
- - **process**: uses processes to run worker modules. This type doesn't work on Win32 platform.
359
+ - **process**: uses processes to run worker modules. This type doesn't work on Windows or JRuby platform.
360
+ - **spawn**: uses processes to run worker modules. This type works on Windows and JRuby platform but available interface of worker module is limited (See also Worker module section).
316
361
 
317
362
 
318
363
  ## Signals
@@ -352,7 +397,7 @@ Graceful shutdown and restart call `Worker#stop` method and wait for completion
352
397
  - **workers** sets number of workers (default: 1) [dynamic reloadable]
353
398
  - **start_worker_delay** sets wait time before starting a new worker (default: 0) [dynamic reloadable]
354
399
  - **start_worker_delay_rand** randomizes start_worker_delay at this ratio (default: 0.2) [dynamic reloadable]
355
- - Multiprocess server: available only when `worker_type` is "process" [dynamic reloadable]
400
+ - Multiprocess server: available only when `worker_type` is "process"
356
401
  - **worker_process_name** changes process name ($0) of workers [dynamic reloadable]
357
402
  - **worker_heartbeat_interval** sets interval of heartbeats in seconds (default: 1.0) [dynamic reloadable]
358
403
  - **worker_heartbeat_timeout** sets timeout of heartbeat in seconds (default: 180) [dynamic reloadable]
@@ -362,6 +407,9 @@ Graceful shutdown and restart call `Worker#stop` method and wait for completion
362
407
  - **worker_immediate_kill_interval** sets the first interval of QUIT signals in seconds (default: 10) [dynamic reloadable]
363
408
  - **worker_immediate_kill_interval_increment** sets increment of QUIT signal interval in seconds (default: 10) [dynamic reloadable]
364
409
  - **worker_immediate_kill_timeout** sets promotion timeout from QUIT to KILL signal in seconds. -1 means no timeout (default: 600) [dynamic reloadable]
410
+ - Multiprocess spawn server: available only when `worker_type` is "spawn"
411
+ - all parameters of multiprocess server excepting worker_process_name
412
+ - **worker_reload_signal** sets the signal to notice configuration reload to a spawned process. Set nil to disable (default: nil)
365
413
  - Logger
366
414
  - **log** sets path to log file. Set "-" for STDOUT (default: STDERR) [dynamic reloadable]
367
415
  - **log_level** log level: trace, debug, info, warn, error or fatal. (default: debug) [dynamic reloadable]
@@ -33,6 +33,7 @@ module ServerEngine
33
33
  :MultiWorkerServer => 'serverengine/multi_worker_server',
34
34
  :MultiProcessServer => 'serverengine/multi_process_server',
35
35
  :MultiThreadServer => 'serverengine/multi_thread_server',
36
+ :MultiSpawnServer => 'serverengine/multi_spawn_server',
36
37
  :ProcessManager => 'serverengine/process_manager',
37
38
  :Worker => 'serverengine/worker',
38
39
  :VERSION => 'serverengine/version',
@@ -0,0 +1,87 @@
1
+ #
2
+ # ServerEngine
3
+ #
4
+ # Copyright (C) 2012-2013 Sadayuki Furuhashi
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ module ServerEngine
19
+
20
+ class MultiSpawnServer < MultiWorkerServer
21
+ def initialize(worker_module, load_config_proc={}, &block)
22
+ @pm = ProcessManager.new(
23
+ auto_tick: false,
24
+ graceful_kill_signal: Daemon::Signals::GRACEFUL_STOP,
25
+ immediate_kill_signal: Daemon::Signals::IMMEDIATE_STOP,
26
+ enable_heartbeat: false,
27
+ )
28
+
29
+ super(worker_module, load_config_proc, &block)
30
+
31
+ @reload_signal = @config[:worker_reload_signal]
32
+ end
33
+
34
+ def run
35
+ super
36
+ ensure
37
+ @pm.close
38
+ end
39
+
40
+ def logger=(logger)
41
+ super
42
+ @pm.logger = logger
43
+ end
44
+
45
+ private
46
+
47
+ def reload_config
48
+ super
49
+
50
+ @pm.configure(@config, prefix: 'worker_')
51
+
52
+ nil
53
+ end
54
+
55
+ def start_worker(wid)
56
+ w = create_worker(wid)
57
+
58
+ w.before_fork
59
+ begin
60
+ pmon = w.spawn(@pm)
61
+ ensure
62
+ w.after_start
63
+ end
64
+
65
+ return WorkerMonitor.new(w, wid, pmon, @reload_signal)
66
+ end
67
+
68
+ def wait_tick
69
+ @pm.tick(0.5)
70
+ end
71
+
72
+ class WorkerMonitor < MultiProcessServer::WorkerMonitor
73
+ def initialize(worker, wid, pmon, reload_signal)
74
+ super(worker, wid, pmon)
75
+ @reload_signal = reload_signal
76
+ end
77
+
78
+ def send_reload
79
+ if @reload_signal
80
+ @pmon.send_signal(@reload_signal) if @pmon
81
+ end
82
+ nil
83
+ end
84
+ end
85
+ end
86
+
87
+ end
@@ -58,6 +58,7 @@ module ServerEngine
58
58
  ServerEngine.dump_uncaught_error(e)
59
59
  end
60
60
  end
61
+ nil
61
62
  end
62
63
 
63
64
  def join
@@ -146,7 +146,7 @@ module ServerEngine
146
146
  rpipe, wpipe = new_pipe_pair
147
147
 
148
148
  begin
149
- options[wpipe.fileno] = wpipe
149
+ options[[wpipe.fileno]] = wpipe
150
150
  if @enable_heartbeat
151
151
  env['SERVERENGINE_HEARTBEAT_PIPE'] = wpipe.fileno.to_s
152
152
  end
@@ -40,6 +40,7 @@ module ServerEngine
40
40
  end
41
41
 
42
42
  def stop(stop_graceful)
43
+ @logger.info "Received #{stop_graceful ? 'graceful' : 'immediate'} stop" if @logger
43
44
  @stop = true
44
45
  nil
45
46
  end
@@ -48,12 +49,14 @@ module ServerEngine
48
49
  end
49
50
 
50
51
  def restart(stop_graceful)
52
+ @logger.info "Received #{stop_graceful ? 'graceful' : 'immediate'} restart" if @logger
51
53
  reload_config
52
54
  @logger.reopen! if @logger
53
55
  nil
54
56
  end
55
57
 
56
58
  def reload
59
+ @logger.info "Received reload" if @logger
57
60
  reload_config
58
61
  @logger.reopen! if @logger
59
62
  nil
@@ -72,6 +72,8 @@ module ServerEngine
72
72
  server_class = MultiProcessServer
73
73
  when 'thread'
74
74
  server_class = MultiThreadServer
75
+ when 'spawn'
76
+ server_class = MultiSpawnServer
75
77
  else
76
78
  raise ArgumentError, "unexpected :worker_type option #{wt}"
77
79
  end
@@ -1,3 +1,3 @@
1
1
  module ServerEngine
2
- VERSION = "1.5.9"
2
+ VERSION = "1.5.10"
3
3
  end
@@ -20,13 +20,16 @@ module ServerEngine
20
20
  class Worker
21
21
  def initialize(server, worker_id)
22
22
  @server = server
23
- @config = server.config
24
23
  @logger = @server.logger
25
24
  @worker_id = worker_id
26
25
  end
27
26
 
28
27
  attr_reader :server, :worker_id
29
- attr_accessor :config, :logger
28
+ attr_accessor :logger
29
+
30
+ def config
31
+ @server.config
32
+ end
30
33
 
31
34
  def before_fork
32
35
  end
@@ -35,6 +38,10 @@ module ServerEngine
35
38
  raise NoMethodError, "Worker#run method is not implemented"
36
39
  end
37
40
 
41
+ def spawn(process_manager)
42
+ raise NoMethodError, "Worker#spawn(process_manager) method is required for worker_type=spawn"
43
+ end
44
+
38
45
  def stop
39
46
  end
40
47
 
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.5.9
4
+ version: 1.5.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sadayuki Furuhashi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-24 00:00:00.000000000 Z
11
+ date: 2014-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sigdump
@@ -75,6 +75,7 @@ files:
75
75
  - lib/serverengine/daemon_logger.rb
76
76
  - lib/serverengine/embedded_server.rb
77
77
  - lib/serverengine/multi_process_server.rb
78
+ - lib/serverengine/multi_spawn_server.rb
78
79
  - lib/serverengine/multi_thread_server.rb
79
80
  - lib/serverengine/multi_worker_server.rb
80
81
  - lib/serverengine/process_manager.rb