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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c2c41ca45cff7f607a22a6861bd7b55e03a70b7
|
4
|
+
data.tar.gz: 97948ab60c218ef17becfb05723270592cc7540c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38ff87ed7b173030bb5293c0d3e89a824efae90b9e87c5a6fefa22f61c3e14b737c4e28cc92e783fc51568f517a5aea5393b69a46de7c8aa26892f24ec0190d9
|
7
|
+
data.tar.gz: 143bfeb1386750fc4275e68d9555551e450ffa57e9c9a408a6fb2e313b421301e4bef62d320ad3a8f0906936bc43f453a92d895ec1103a2735478f1561b3d76a
|
data/.gitignore
CHANGED
data/Changelog
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
2016-08-23 version 2.0.0:
|
2
|
+
|
3
|
+
* Add windows-pr gem dependency to get ruby_bin_path correctly
|
4
|
+
* Add command sender feature to use pipe to control workers for Windows
|
5
|
+
* Delete MultiprocessLogDevice implementation to use Ruby's one always. This
|
6
|
+
means removal of backward workaround code for Ruby < 2.1.
|
7
|
+
* Refactor modules and methods to clean internal file dependency Internal
|
8
|
+
symbol `ServerEngine::Daemon::Signals` is moved to `ServerEngine::Signals`
|
9
|
+
* Add example script to run servers
|
10
|
+
* Fix required Ruby version to 2.1 or later
|
11
|
+
|
1
12
|
2016-05-19 version 1.6.4:
|
2
13
|
|
3
14
|
* Refactor to delete some warnings
|
data/README.md
CHANGED
@@ -68,7 +68,7 @@ se = ServerEngine.create(nil, MyWorker, {
|
|
68
68
|
se.run
|
69
69
|
```
|
70
70
|
|
71
|
-
Send `TERM` signal to kill the daemon. See also **Signals** section bellow for details.
|
71
|
+
Send `TERM` signal (or `KILL` on Windows) to kill the daemon. See also **Signals** section bellow for details.
|
72
72
|
|
73
73
|
|
74
74
|
### Multiprocess server
|
@@ -141,6 +141,12 @@ ServerEngine provides **worker_type: "spawn"** for those platforms (This is stil
|
|
141
141
|
|
142
142
|
What you need to implement at least to use worker_type: "spawn" is `def spawn(process_manager)` method. You will call `process_manager.spawn` at the method, where `spawn` is same with `Process.spawn` excepting return value.
|
143
143
|
|
144
|
+
In addition, Windows does not support signals. ServerEngine provides **command_sender: "pipe"** for Windows (and for other platforms, if you want to use it).
|
145
|
+
When using **command_sender: "pipe"**, the child process have to handle commands sent from parent process via STDIN.
|
146
|
+
On Windows, **command_sender: "pipe"** is default.
|
147
|
+
|
148
|
+
You can call `Server#stop(stop_graceful)` and `Server#restart(stop_graceful)` instead of sending signals.
|
149
|
+
|
144
150
|
```ruby
|
145
151
|
module MyWorker
|
146
152
|
def spawn(process_manager)
|
@@ -155,8 +161,20 @@ module MyWorker
|
|
155
161
|
logger = ServerEngine::DaemonLogger.new(conf[:log] || STDOUT, conf)
|
156
162
|
|
157
163
|
@stop = false
|
158
|
-
|
159
|
-
|
164
|
+
command_pipe = STDIN.dup
|
165
|
+
STDIN.reopen(File::NULL)
|
166
|
+
Thread.new do
|
167
|
+
until @stop
|
168
|
+
case command_pipe.gets.chomp
|
169
|
+
when "GRACEFUL_STOP"
|
170
|
+
@stop = true
|
171
|
+
when "IMMEDIATE_STOP"
|
172
|
+
@stop = true
|
173
|
+
when "GRACEFUL_RESTART", "IMMEDIATE_RESTART"
|
174
|
+
# do something...
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
160
178
|
|
161
179
|
until @stop
|
162
180
|
logger.info 'Awesome work!'
|
@@ -169,6 +187,7 @@ end
|
|
169
187
|
|
170
188
|
se = ServerEngine.create(nil, MyWorker, {
|
171
189
|
worker_type: 'spawn',
|
190
|
+
command_sender: 'pipe',
|
172
191
|
log: 'myserver.log',
|
173
192
|
})
|
174
193
|
se.run
|
@@ -213,6 +232,7 @@ se = ServerEngine.create(nil, MyWorker, {
|
|
213
232
|
se.run
|
214
233
|
```
|
215
234
|
|
235
|
+
This auto restart reature will be suppressed for workers which exits with exit code specified by `unrecoverable_exit_codes`. At this case, whole process will exit without error (exit code 0).
|
216
236
|
|
217
237
|
## Live restart
|
218
238
|
|
@@ -304,6 +324,10 @@ Send `USR2` signal to reload configuration file.
|
|
304
324
|
Immediate shutdown and restart send SIGQUIT signal to worker processes which kills the processes.
|
305
325
|
Graceful shutdown and restart call `Worker#stop` method and wait for completion of `Worker#run` method.
|
306
326
|
|
327
|
+
Note that signals are not supported on Windows.
|
328
|
+
You have to use piped command instead of signals on Windows.
|
329
|
+
See also **Multiprocess server on Windows and JRuby platforms** section.
|
330
|
+
|
307
331
|
|
308
332
|
## Utilities
|
309
333
|
|
@@ -388,6 +412,8 @@ se = ServerEngine.create(MyServer, MyWorker, {
|
|
388
412
|
se.run
|
389
413
|
```
|
390
414
|
|
415
|
+
See also [examples](https://github.com/fluent/serverengine/tree/master/examples).
|
416
|
+
|
391
417
|
|
392
418
|
## Module API
|
393
419
|
|
@@ -464,6 +490,8 @@ Available methods are different depending on `worker_type`. ServerEngine support
|
|
464
490
|
- **worker_immediate_kill_interval** sets the first interval of QUIT signals in seconds (default: 10) [dynamic reloadable]
|
465
491
|
- **worker_immediate_kill_interval_increment** sets increment of QUIT signal interval in seconds (default: 10) [dynamic reloadable]
|
466
492
|
- **worker_immediate_kill_timeout** sets promotion timeout from QUIT to KILL signal in seconds. -1 means no timeout (default: 600) [dynamic reloadable]
|
493
|
+
- **unrecoverable_exit_codes** handles worker processes, which exits with code included in this value, as unrecoverable (not to restart) (default: [])
|
494
|
+
- **stop_immediately_at_unrecoverable_exit** stops server immediately if a worker exits with unrecoverable exit status (default: false)
|
467
495
|
- Multiprocess spawn server: available only when `worker_type` is "spawn"
|
468
496
|
- all parameters of multiprocess server excepting worker_process_name
|
469
497
|
- **worker_reload_signal** sets the signal to notice configuration reload to a spawned process. Set nil to disable (default: nil)
|
data/Rakefile
CHANGED
@@ -6,8 +6,21 @@ require 'rake/clean'
|
|
6
6
|
|
7
7
|
require 'rspec/core/rake_task'
|
8
8
|
|
9
|
-
RSpec::Core::RakeTask.new(:spec)
|
10
|
-
|
9
|
+
RSpec::Core::RakeTask.new(:spec)
|
10
|
+
task :default => [:spec, :build]
|
11
|
+
|
12
|
+
# 1. update Changelog and lib/serverengine/version.rb
|
13
|
+
# 2. bundle && bundle exec rake build:all
|
14
|
+
# 3. release 3 packages built on pkg/ directory
|
15
|
+
namespace :build do
|
16
|
+
desc 'Build gems for all platforms'
|
17
|
+
task :all do
|
18
|
+
Bundler.with_clean_env do
|
19
|
+
%w[ruby x86-mingw32 x64-mingw32].each do |name|
|
20
|
+
ENV['GEM_BUILD_FAKE_PLATFORM'] = name
|
21
|
+
Rake::Task["build"].execute
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
11
25
|
end
|
12
26
|
|
13
|
-
task :default => [:spec, :build]
|
data/appveyor.yml
CHANGED
@@ -10,9 +10,15 @@ test_script:
|
|
10
10
|
|
11
11
|
environment:
|
12
12
|
matrix:
|
13
|
-
- ruby_version: "
|
14
|
-
|
15
|
-
- ruby_version: "
|
16
|
-
|
13
|
+
- ruby_version: "23-x64"
|
14
|
+
devkit: C:\Ruby23-x64\DevKit
|
15
|
+
- ruby_version: "23"
|
16
|
+
devkit: C:\Ruby23\DevKit
|
17
|
+
- ruby_version: "22-x64"
|
18
|
+
devkit: C:\Ruby23-x64\DevKit
|
17
19
|
- ruby_version: "22"
|
18
|
-
|
20
|
+
devkit: C:\Ruby23\DevKit
|
21
|
+
- ruby_version: "21-x64"
|
22
|
+
devkit: C:\Ruby23-x64\DevKit
|
23
|
+
- ruby_version: "21"
|
24
|
+
devkit: C:\Ruby23\DevKit
|
data/examples/server.rb
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'serverengine'
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
# This is a script to run ServerEngine and SocketManager as a real process.
|
7
|
+
# bundle exec ruby example/server.rb [-t TYPE] [-w NUM]
|
8
|
+
# available type of workers are: embedded(default), process, thread, spawn
|
9
|
+
|
10
|
+
foreground = false
|
11
|
+
supervisor = false
|
12
|
+
worker_type = nil
|
13
|
+
workers = 4
|
14
|
+
exit_with_code = nil
|
15
|
+
exit_at_seconds = 5
|
16
|
+
exit_at_random = false
|
17
|
+
stop_immediately_at_exit = false
|
18
|
+
unrecoverable_exit_codes = []
|
19
|
+
|
20
|
+
opt = OptionParser.new
|
21
|
+
opt.on('-f'){ foreground = true }
|
22
|
+
opt.on('-x'){ supervisor = true }
|
23
|
+
opt.on('-t TYPE'){|v| worker_type = v }
|
24
|
+
opt.on('-w NUM'){|v| workers = v.to_i }
|
25
|
+
opt.on('-e NUM'){|v| exit_with_code = v.to_i }
|
26
|
+
opt.on('-s NUM'){|v| exit_at_seconds = v.to_i }
|
27
|
+
opt.on('-r'){ exit_at_random = true }
|
28
|
+
opt.on('-i'){ stop_immediately_at_exit = true }
|
29
|
+
opt.on('-u NUM'){|v| unrecoverable_exit_codes << v.to_i }
|
30
|
+
opt.parse!(ARGV)
|
31
|
+
|
32
|
+
if exit_with_code
|
33
|
+
ENV['EXIT_WITH_CODE'] = exit_with_code.to_s
|
34
|
+
ENV['EXIT_AT_SECONDS'] = exit_at_seconds.to_s
|
35
|
+
if exit_at_random
|
36
|
+
ENV['EXIT_AT_RANDOM'] = 'true'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module MyServer
|
41
|
+
attr_reader :socket_manager_path
|
42
|
+
|
43
|
+
def before_run
|
44
|
+
@socket_manager_path = ServerEngine::SocketManager::Server.generate_path
|
45
|
+
@socket_manager_server = ServerEngine::SocketManager::Server.open(@socket_manager_path)
|
46
|
+
rescue Exception => e
|
47
|
+
logger.error "unexpected error in server, class #{e.class}: #{e.message}"
|
48
|
+
raise
|
49
|
+
end
|
50
|
+
|
51
|
+
def after_run
|
52
|
+
logger.info "Server stopped."
|
53
|
+
@socket_manager_server.close
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
module MyWorker
|
58
|
+
def initialize
|
59
|
+
@stop = false
|
60
|
+
@socket_manager = ServerEngine::SocketManager::Client.new(server.socket_manager_path)
|
61
|
+
@exit_with_code = ENV.key?('EXIT_WITH_CODE') ? ENV['EXIT_WITH_CODE'].to_i : nil
|
62
|
+
@exit_at_seconds = ENV.key?('EXIT_AT_SECONDS') ? ENV['EXIT_AT_SECONDS'].to_i : nil
|
63
|
+
@exit_at_random = ENV.key?('EXIT_AT_RANDOM')
|
64
|
+
end
|
65
|
+
|
66
|
+
def main
|
67
|
+
# test to listen the same port
|
68
|
+
logger.info "Starting to run Worker."
|
69
|
+
_listen_sock = @socket_manager.listen_tcp('0.0.0.0', 12345)
|
70
|
+
stop_at = if @exit_with_code
|
71
|
+
stop_seconds = @exit_at_random ? rand(@exit_at_seconds) : @exit_at_seconds
|
72
|
+
logger.info "Stop #{stop_seconds} seconds later with code #{@exit_with_code}."
|
73
|
+
Time.now + stop_seconds
|
74
|
+
else
|
75
|
+
nil
|
76
|
+
end
|
77
|
+
until @stop
|
78
|
+
if stop_at && Time.now >= stop_at
|
79
|
+
logger.info "Exitting with code #{@exit_with_code}"
|
80
|
+
exit! @exit_with_code
|
81
|
+
end
|
82
|
+
logger.info "Awesome work!"
|
83
|
+
sleep 1
|
84
|
+
end
|
85
|
+
logger.info "Exitting"
|
86
|
+
rescue Exception => e
|
87
|
+
logger.warn "unexpected error, class #{e.class}: #{e.message}"
|
88
|
+
raise
|
89
|
+
end
|
90
|
+
|
91
|
+
def stop
|
92
|
+
@stop = true
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
module MySpawnWorker
|
97
|
+
def spawn(process_manager)
|
98
|
+
env = {
|
99
|
+
'SERVER_ENGINE_CONFIG' => config.to_json,
|
100
|
+
'SERVER_ENGINE_SOCKET_MANAGER_PATH' => server.socket_manager_path,
|
101
|
+
}
|
102
|
+
if ENV['EXIT_WITH_CODE']
|
103
|
+
env['EXIT_WITH_CODE'] = ENV['EXIT_WITH_CODE']
|
104
|
+
env['EXIT_AT_SECONDS'] = ENV['EXIT_AT_SECONDS']
|
105
|
+
if ENV['EXIT_AT_RANDOM']
|
106
|
+
env['EXIT_AT_RANDOM'] = 'true'
|
107
|
+
end
|
108
|
+
end
|
109
|
+
process_manager.spawn(env, "ruby", File.expand_path("../spawn_worker_script.rb", __FILE__))
|
110
|
+
rescue Exception => e
|
111
|
+
logger.error "unexpected error, class #{e.class}: #{e.message}"
|
112
|
+
raise
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
opts = {
|
117
|
+
daemonize: !foreground,
|
118
|
+
daemon_process_name: 'mydaemon',
|
119
|
+
supervisor: supervisor,
|
120
|
+
log: 'myserver.log',
|
121
|
+
pid_path: 'myserver.pid',
|
122
|
+
worker_type: worker_type,
|
123
|
+
workers: workers,
|
124
|
+
}
|
125
|
+
if stop_immediately_at_exit
|
126
|
+
opts[:stop_immediately_at_unrecoverable_exit] = true
|
127
|
+
end
|
128
|
+
unless unrecoverable_exit_codes.empty?
|
129
|
+
opts[:unrecoverable_exit_codes] = unrecoverable_exit_codes
|
130
|
+
end
|
131
|
+
|
132
|
+
worker_klass = MyWorker
|
133
|
+
if worker_type == 'spawn'
|
134
|
+
worker_klass = MySpawnWorker
|
135
|
+
end
|
136
|
+
se = ServerEngine.create(MyServer, worker_klass, opts)
|
137
|
+
|
138
|
+
se.run
|
@@ -0,0 +1,38 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path("../..", __FILE__)
|
2
|
+
|
3
|
+
require 'serverengine'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
begin
|
7
|
+
conf = JSON.parse(ENV['SERVER_ENGINE_CONFIG'], symbolize_names: true)
|
8
|
+
logger = ServerEngine::DaemonLogger.new(conf[:log] || STDOUT, conf)
|
9
|
+
logger.info "Starting to run Worker."
|
10
|
+
socket_manager = ServerEngine::SocketManager::Client.new(ENV['SERVER_ENGINE_SOCKET_MANAGER_PATH'])
|
11
|
+
exit_with_code = ENV.key?('EXIT_WITH_CODE') ? ENV['EXIT_WITH_CODE'].to_i : nil
|
12
|
+
exit_at_seconds = ENV.key?('EXIT_AT_SECONDS') ? ENV['EXIT_AT_SECONDS'].to_i : nil
|
13
|
+
exit_at_random = ENV.key?('EXIT_AT_RANDOM')
|
14
|
+
stop_at = if exit_with_code
|
15
|
+
stop_seconds = exit_at_random ? rand(exit_at_seconds) : exit_at_seconds
|
16
|
+
logger.info "Stop #{stop_seconds} seconds later with code #{exit_with_code}."
|
17
|
+
Time.now + stop_seconds
|
18
|
+
else
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
|
22
|
+
@stop = false
|
23
|
+
trap(:SIGTERM) { @stop = true }
|
24
|
+
trap(:SIGINT) { @stop = true }
|
25
|
+
|
26
|
+
_listen_sock = socket_manager.listen_tcp('0.0.0.0', 12345)
|
27
|
+
until @stop
|
28
|
+
if stop_at && Time.now >= stop_at
|
29
|
+
logger.info "Exitting with code #{exit_with_code}"
|
30
|
+
exit! exit_with_code
|
31
|
+
end
|
32
|
+
logger.info 'Awesome work!'
|
33
|
+
sleep 1
|
34
|
+
end
|
35
|
+
logger.info 'Exitting'
|
36
|
+
rescue Exception => e
|
37
|
+
logger.error "unexpected error in spawn worker, class #{e.class}: #{e.message}"
|
38
|
+
end
|
@@ -15,10 +15,9 @@
|
|
15
15
|
# See the License for the specific language governing permissions and
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
|
-
|
19
|
-
|
20
|
-
require 'thread'
|
18
|
+
require 'thread'
|
21
19
|
|
20
|
+
module ServerEngine
|
22
21
|
class BlockingFlag
|
23
22
|
def initialize
|
24
23
|
@set = false
|
@@ -0,0 +1,89 @@
|
|
1
|
+
#
|
2
|
+
# ServerEngine
|
3
|
+
#
|
4
|
+
# Copyright (C) 2012-2013 FURUHASHI Sadayuki
|
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
|
+
require 'serverengine/signals'
|
19
|
+
|
20
|
+
module ServerEngine
|
21
|
+
module CommandSender
|
22
|
+
# requires send_signal method or @pid
|
23
|
+
module Signal
|
24
|
+
private
|
25
|
+
def _stop(graceful)
|
26
|
+
_send_signal(!ServerEngine.windows? && graceful ? Signals::GRACEFUL_STOP : Signals::IMMEDIATE_STOP)
|
27
|
+
end
|
28
|
+
|
29
|
+
def _restart(graceful)
|
30
|
+
_send_signal(graceful ? Signals::GRACEFUL_RESTART : Signals::IMMEDIATE_RESTART)
|
31
|
+
end
|
32
|
+
|
33
|
+
def _reload
|
34
|
+
_send_signal(Signals::RELOAD)
|
35
|
+
end
|
36
|
+
|
37
|
+
def _detach
|
38
|
+
_send_signal(Signals::DETACH)
|
39
|
+
end
|
40
|
+
|
41
|
+
def _dump
|
42
|
+
_send_signal(Signals::DUMP)
|
43
|
+
end
|
44
|
+
|
45
|
+
def _send_signal(sig)
|
46
|
+
if respond_to?(:send_signal, true)
|
47
|
+
send_signal(sig)
|
48
|
+
else
|
49
|
+
Process.kill(sig, @pid)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# requires @command_sender_pipe
|
55
|
+
module Pipe
|
56
|
+
private
|
57
|
+
def _stop(graceful)
|
58
|
+
begin
|
59
|
+
_send_command(graceful ? "GRACEFUL_STOP" : "IMMEDIATE_STOP")
|
60
|
+
rescue Errno::EPIPE
|
61
|
+
# already stopped, then nothing to do
|
62
|
+
ensure
|
63
|
+
@command_sender_pipe.close rescue nil
|
64
|
+
@command_sender_pipe = nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def _restart(graceful)
|
69
|
+
_send_command(graceful ? "GRACEFUL_RESTART" : "IMMEDIATE_RESTART")
|
70
|
+
end
|
71
|
+
|
72
|
+
def _reload
|
73
|
+
_send_command("RELOAD")
|
74
|
+
end
|
75
|
+
|
76
|
+
def _detach
|
77
|
+
_send_command("DETACH")
|
78
|
+
end
|
79
|
+
|
80
|
+
def _dump
|
81
|
+
_send_command("DUMP")
|
82
|
+
end
|
83
|
+
|
84
|
+
def _send_command(cmd)
|
85
|
+
@command_sender_pipe.write cmd + "\n"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|