navy 1.0.7 → 1.1.0
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/examples/navy.conf.rb +240 -194
- data/lib/navy/admiral.rb +11 -4
- data/lib/navy/admiral/orders.rb +3 -0
- data/lib/navy/captain.rb +8 -4
- data/lib/navy/captain/orders.rb +4 -0
- data/lib/navy/orders.rb +4 -3
- data/lib/navy/rank.rb +20 -4
- data/lib/navy/speak.rb +11 -0
- data/lib/navy/version.rb +1 -1
- metadata +10 -10
data/examples/navy.conf.rb
CHANGED
@@ -56,229 +56,275 @@ pid "/tmp/navy.pid"
|
|
56
56
|
|
57
57
|
# end
|
58
58
|
|
59
|
-
module Jack
|
59
|
+
# module Jack
|
60
60
|
|
61
|
-
|
61
|
+
# SELF_PIPE = []
|
62
62
|
|
63
|
-
|
63
|
+
# extend self
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
|
65
|
+
# def call(officer)
|
66
|
+
# trap(:QUIT) { sleep 120; exit }
|
67
|
+
# trap(:TERM) { exit }
|
68
68
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
69
|
+
# # raise "HELLO"
|
70
|
+
# n = 0
|
71
|
+
# loop do
|
72
|
+
# Navy.logger.info "#{n} jack called (officer=#{officer.number}) pid: #{officer.officer_pid}"
|
73
|
+
# # Jack.logger.info "#{n} jack logger (officer=#{officer.number}) pid: #{officer.officer_pid}"
|
74
|
+
# # Navy.logger.info "START_CTX: #{START_CTX.inspect}"
|
75
|
+
# # Navy.logger.info "Navy::Admiral::CAPTAINS: #{Navy::Admiral::CAPTAINS.inspect}"
|
76
|
+
# # Navy.logger.info "Navy::Admiral::OFFICERS: #{Navy::Captain::OFFICERS.inspect}"
|
77
|
+
# sleep officer.number == 0 ? 0.5 : 1
|
78
|
+
# n += 1
|
79
|
+
# end
|
80
|
+
# end
|
81
81
|
|
82
|
-
|
83
|
-
|
84
|
-
|
82
|
+
# def logger
|
83
|
+
# @logger ||= Logger.new('/tmp/jack.log')
|
84
|
+
# end
|
85
85
|
|
86
|
-
|
87
|
-
|
88
|
-
|
86
|
+
# def logger=(val)
|
87
|
+
# @logger = val
|
88
|
+
# end
|
89
89
|
|
90
|
-
|
91
|
-
|
92
|
-
|
90
|
+
# def readers
|
91
|
+
# @readers ||= {}
|
92
|
+
# end
|
93
93
|
|
94
|
-
|
95
|
-
|
96
|
-
|
94
|
+
# def reader=(val)
|
95
|
+
# @reader = val
|
96
|
+
# end
|
97
97
|
|
98
|
-
|
99
|
-
|
100
|
-
|
98
|
+
# def writer=(val)
|
99
|
+
# @writer = val
|
100
|
+
# end
|
101
101
|
|
102
|
-
|
103
|
-
|
104
|
-
|
102
|
+
# def reader
|
103
|
+
# @reader
|
104
|
+
# end
|
105
105
|
|
106
|
-
|
107
|
-
|
108
|
-
|
106
|
+
# def writer
|
107
|
+
# @writer
|
108
|
+
# end
|
109
109
|
|
110
|
-
|
111
|
-
|
112
|
-
|
110
|
+
# def main_reader=(val)
|
111
|
+
# @main_reader = val
|
112
|
+
# end
|
113
113
|
|
114
|
-
|
115
|
-
|
116
|
-
|
114
|
+
# def main_writer=(val)
|
115
|
+
# @main_writer = val
|
116
|
+
# end
|
117
117
|
|
118
|
-
|
119
|
-
|
120
|
-
|
118
|
+
# def main_reader
|
119
|
+
# @main_reader
|
120
|
+
# end
|
121
121
|
|
122
|
-
|
123
|
-
|
124
|
-
|
122
|
+
# def main_writer
|
123
|
+
# @main_writer
|
124
|
+
# end
|
125
125
|
|
126
|
-
|
127
|
-
|
128
|
-
|
126
|
+
# def threads
|
127
|
+
# @threads ||= {}
|
128
|
+
# end
|
129
129
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
130
|
+
# def start
|
131
|
+
# @thread ||= Thread.new do
|
132
|
+
# loop do
|
133
|
+
# IO.select([ SELF_PIPE[0] ], nil, nil, 0.1) or next
|
134
|
+
# data = SELF_PIPE[0].gets
|
135
|
+
# next unless data
|
136
|
+
# data.force_encoding("BINARY") if data.respond_to?(:force_encoding)
|
137
|
+
# pid, message = data.split(',', 2)
|
138
|
+
# Jack.logger.info "YOUR PID WAS: #{pid}; #{message.strip}"
|
139
|
+
# # Jack.logger.info data
|
140
|
+
# end
|
141
|
+
# end
|
142
|
+
# end
|
143
143
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
144
|
+
# def stop
|
145
|
+
# if @thread
|
146
|
+
# @thread.terminate rescue nil
|
147
|
+
# end
|
148
|
+
# SELF_PIPE.each { |io| io.close rescue nil }
|
149
|
+
# end
|
150
150
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
end
|
151
|
+
# # def main_thread(captain = nil)
|
152
|
+
# # @main_thread = nil if @main_thread and @main_thread.stop?
|
153
|
+
# # if @main_thread.nil?
|
154
|
+
# # # Jack.main_reader.close rescue nil
|
155
|
+
# # # Jack.main_writer.close rescue nil
|
156
|
+
# # Jack.main_reader, Jack.main_writer = IO.pipe
|
157
|
+
# # Jack.main_reader.sync = true
|
158
|
+
# # Jack.main_writer.sync = true
|
159
|
+
# # end
|
160
|
+
# # @main_thread ||= Thread.new do
|
161
|
+
# # readers = [Jack.main_reader]
|
162
|
+
# # loop do
|
163
|
+
# # rs, ws = IO.select(readers, [], [], 1)
|
164
|
+
# # (rs || []).each do |r|
|
165
|
+
# # data = r.gets
|
166
|
+
# # next unless data
|
167
|
+
# # data.force_encoding("BINARY") if data.respond_to?(:force_encoding)
|
168
|
+
# # ps, message = data.split(",", 2)
|
169
|
+
# # Jack.logger.info "pid: #{ps}, message: #{message.to_s.strip}"
|
170
|
+
# # end
|
171
|
+
# # end
|
172
|
+
# # end
|
173
|
+
# # end
|
174
|
+
# end
|
175
175
|
|
176
176
|
captain :jack do
|
177
177
|
|
178
|
-
stderr_path "/tmp/navy-jack-err.log"
|
179
|
-
# stdout_path "/tmp/navy-jack-out.log"
|
180
|
-
|
181
|
-
preload do |captain|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
end
|
178
|
+
# stderr_path "/tmp/navy-jack-err.log"
|
179
|
+
# # stdout_path "/tmp/navy-jack-out.log"
|
180
|
+
|
181
|
+
# preload do |captain|
|
182
|
+
# captain.logger.warn "captain=#{captain.label} preload"
|
183
|
+
# Jack::SELF_PIPE.each { |io| io.close rescue nil }
|
184
|
+
# # Jack::SELF_PIPE.replace(Kgio::Pipe.new)
|
185
|
+
# Jack::SELF_PIPE.replace(IO.pipe)
|
186
|
+
# Jack::SELF_PIPE.each { |io| io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC); io.sync = true }
|
187
|
+
# Jack.logger.info "preload"
|
188
|
+
# Jack.start
|
189
|
+
# end
|
190
190
|
|
191
|
-
before_fork do |captain, officer|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
end
|
191
|
+
# before_fork do |captain, officer|
|
192
|
+
# # Jack.main_thread(captain)
|
193
|
+
# captain.logger.warn "captain=#{captain.label} before_fork"
|
194
|
+
# officer.logger.warn "(#{captain.label}) officer=#{officer.number} before_fork"
|
195
|
+
# # if r = Jack.readers.delete(officer.number)
|
196
|
+
# # r.close
|
197
|
+
# # end
|
198
|
+
# # Jack.readers[officer.number], Jack.writer = IO.pipe
|
199
|
+
# # Jack.reader = Jack.readers[officer.number]
|
200
|
+
# # Jack.reader.sync = true
|
201
|
+
# end
|
202
202
|
|
203
|
-
after_fork do |captain, officer|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
end
|
203
|
+
# after_fork do |captain, officer|
|
204
|
+
# # Jack.reader.close # we don't read
|
205
|
+
# # Jack.writer.sync = true
|
206
|
+
# captain.logger.warn "captain=#{captain.label} after_fork"
|
207
|
+
# officer.logger.warn "(#{captain.label}) officer=#{officer.number} after_fork"
|
208
|
+
# # $stdout.reopen Jack.writer
|
209
|
+
# # $stderr.reopen Jack.writer
|
210
|
+
|
211
|
+
# reader, writer = IO.pipe
|
212
|
+
# $stdout.reopen writer
|
213
|
+
# $stdout.reopen writer
|
214
|
+
|
215
|
+
# Thread.new do
|
216
|
+
# until reader.eof?
|
217
|
+
# Jack::SELF_PIPE[1].puts "%s,%s" % [ officer.officer_pid, reader.gets ]
|
218
|
+
# end
|
219
|
+
# end
|
220
|
+
# end
|
221
221
|
|
222
|
-
after_stop do |captain, graceful|
|
223
|
-
|
224
|
-
end
|
222
|
+
# after_stop do |captain, graceful|
|
223
|
+
# Jack.stop if graceful
|
224
|
+
# end
|
225
225
|
|
226
|
-
post_fork do |captain, officer|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
end
|
226
|
+
# post_fork do |captain, officer|
|
227
|
+
# # Jack.writer.close # we don't write
|
228
|
+
# # if t = Jack.threads[officer.number]
|
229
|
+
# # t.terminate unless t.stop?
|
230
|
+
# # else
|
231
|
+
# # Jack.threads[officer.number] = Thread.new do
|
232
|
+
# # reader = Jack.reader
|
233
|
+
# # until reader.eof?
|
234
|
+
# # Jack::SELF_PIPE[1].puts "%s,%s" % [ officer.officer_pid, reader.gets ]
|
235
|
+
# # end
|
236
|
+
# # end
|
237
|
+
# # end
|
238
|
+
# # Jack.reader.lcose
|
239
|
+
# # Thread.new do
|
240
|
+
# # # Jack.main_reader.close
|
241
|
+
# # # Jack.main_writer.close
|
242
|
+
# # loop do
|
243
|
+
# # rs, ws = IO.select([Jack.reader], [], [], 1)
|
244
|
+
# # (rs || []).each do |r|
|
245
|
+
# # data = r.gets
|
246
|
+
# # next unless data
|
247
|
+
# # data.force_encoding("BINARY") if data.respond_to?(:force_encoding)
|
248
|
+
# # # ps, message = data.split(",", 2)
|
249
|
+
# # # color = colors[ps.split(".").first]
|
250
|
+
# # # info message, ps, color
|
251
|
+
# # # Jack.mutex.synchronize do
|
252
|
+
# # # Jack.logger.info "pid: #{ps}, message: #{message}"
|
253
|
+
# # # Jack.logger.info data.strip
|
254
|
+
# # # end
|
255
|
+
# # Jack.main_writer.puts "pidpidpid: #{officer.officer_pid}, message: #{data}"
|
256
|
+
# # end
|
257
|
+
# # end
|
258
|
+
# # end
|
259
|
+
# # Thread.new do
|
260
|
+
# # reader, writer = Jack.reader, Jack.writer
|
261
|
+
# # loop do
|
262
|
+
# # rs, ws = IO.select([reader], [], [], 1)
|
263
|
+
# # (rs || []).each do |r|
|
264
|
+
# # data = r.gets
|
265
|
+
# # next unless data
|
266
|
+
# # data.force_encoding("BINARY") if data.respond_to?(:force_encoding)
|
267
|
+
# # # ps, message = data.split(",", 2)
|
268
|
+
# # # color = colors[ps.split(".").first]
|
269
|
+
# # # info message, ps, color
|
270
|
+
# # # Jack.mutex.synchronize do
|
271
|
+
# # # Jack.logger.info "pid: #{ps}, message: #{message}"
|
272
|
+
# # writer.write "%s,%s" [ '13', data ]
|
273
|
+
# # # end
|
274
|
+
# # end
|
275
|
+
# # end
|
276
|
+
# # end
|
277
|
+
# end
|
278
|
+
|
279
|
+
# preload do |captain|
|
280
|
+
# require 'fileutils'
|
281
|
+
# require 'rainbow'
|
282
|
+
# Sickill::Rainbow.enabled = true
|
283
|
+
# end
|
278
284
|
|
279
285
|
respawn_limit 15, 5
|
280
286
|
|
281
|
-
|
287
|
+
patience 5
|
288
|
+
|
289
|
+
# heartbeat do |captain|
|
290
|
+
# captain.logger.info "captain=#{captain.label} heartbeat".color(:red)
|
291
|
+
# captain.class::OFFICERS.each do |officer_pid, officer|
|
292
|
+
# # begin
|
293
|
+
# name = "/tmp/ps#{officer_pid}"
|
294
|
+
# system("ps -o rss= -p #{officer_pid} > #{name}")
|
295
|
+
# mem_usage = (::File.read(name) rescue 0).to_s.strip.to_i
|
296
|
+
# ::FileUtils.rm_f(name)
|
297
|
+
|
298
|
+
# if mem_usage > 2000
|
299
|
+
# captain.send(:kill_officer, :TERM, officer_pid)
|
300
|
+
# captain.logger.info "captain=#{captain.label} officer=#{officer.number} over memory limit, sending TERM (pid: #{officer_pid}, mem: #{mem_usage} KB)".color(:yellow)
|
301
|
+
# else
|
302
|
+
|
303
|
+
# # mem_usage = `ps -o rss= -p #{officer_pid}`.to_s.strip
|
304
|
+
# # mem_usage = 20
|
305
|
+
# captain.logger.info "captain=#{captain.label} checking officer=#{officer.number} (pid: #{officer_pid}, mem: #{mem_usage} KB)".color(:green)
|
306
|
+
# # rescue => e
|
307
|
+
# # captain.logger.error "captain=#{captain.label} checking officer=#{officer.number} (pid: #{pid}) error: #{e.inspect}".color(:red)
|
308
|
+
# end
|
309
|
+
# end
|
310
|
+
# end
|
311
|
+
|
312
|
+
officers 4 do |officer|
|
313
|
+
trap(:QUIT) { sleep 120; exit }
|
314
|
+
trap(:TERM) { exit }
|
315
|
+
|
316
|
+
# raise "HELLO"
|
317
|
+
n = 0
|
318
|
+
loop do
|
319
|
+
Navy.logger.info "#{n} jack called (officer=#{officer.number}) pid: #{officer.officer_pid}"
|
320
|
+
# Jack.logger.info "#{n} jack logger (officer=#{officer.number}) pid: #{officer.officer_pid}"
|
321
|
+
# Navy.logger.info "START_CTX: #{START_CTX.inspect}"
|
322
|
+
# Navy.logger.info "Navy::Admiral::CAPTAINS: #{Navy::Admiral::CAPTAINS.inspect}"
|
323
|
+
# Navy.logger.info "Navy::Admiral::OFFICERS: #{Navy::Captain::OFFICERS.inspect}"
|
324
|
+
sleep officer.number == 0 ? 0.5 : 1
|
325
|
+
n += 1
|
326
|
+
end
|
327
|
+
end
|
282
328
|
# officers 2 do |officer|
|
283
329
|
# trap(:QUIT) { exit }
|
284
330
|
# trap(:TERM) { exit }
|
data/lib/navy/admiral.rb
CHANGED
@@ -26,8 +26,11 @@ class Navy::Admiral < Navy::Rank
|
|
26
26
|
Dir.pwd
|
27
27
|
end
|
28
28
|
|
29
|
-
|
30
|
-
|
29
|
+
## callbacks ##
|
30
|
+
attr_accessor :before_exec
|
31
|
+
|
32
|
+
attr_accessor :admiral_pid, :captains
|
33
|
+
attr_reader :options
|
31
34
|
|
32
35
|
def initialize(options = {})
|
33
36
|
self.orig_stderr = $stderr.dup
|
@@ -78,6 +81,7 @@ class Navy::Admiral < Navy::Rank
|
|
78
81
|
when nil
|
79
82
|
# avoid murdering workers after our master process (or the
|
80
83
|
# machine) comes out of suspend/hibernation
|
84
|
+
heartbeat.call(self) if heartbeat
|
81
85
|
if (last_check + @timeout) >= (last_check = Time.now)
|
82
86
|
sleep_time = murder_lazy_captains
|
83
87
|
logger.debug("would normally murder lazy captains") if $DEBUG
|
@@ -132,12 +136,15 @@ class Navy::Admiral < Navy::Rank
|
|
132
136
|
# Terminates all captains, but does not exit admiral process
|
133
137
|
def stop(graceful = true)
|
134
138
|
before_stop.call(self, graceful) if before_stop
|
135
|
-
limit = Time.now +
|
136
|
-
until CAPTAINS.empty? || Time.now > limit
|
139
|
+
limit = Time.now + patience
|
140
|
+
until CAPTAINS.empty? || (n = Time.now) > limit
|
137
141
|
kill_each_captain(graceful ? :QUIT : :TERM)
|
138
142
|
sleep(0.1)
|
139
143
|
reap_all_captains
|
140
144
|
end
|
145
|
+
if n and n > limit
|
146
|
+
logger.debug "admiral patience exceeded by #{n - limit} seconds (limit #{patience} seconds)" if $DEBUG
|
147
|
+
end
|
141
148
|
kill_each_captain(:KILL)
|
142
149
|
after_stop.call(self, graceful) if after_stop
|
143
150
|
end
|
data/lib/navy/admiral/orders.rb
CHANGED
@@ -17,6 +17,9 @@ class Navy::Admiral::Orders < Navy::Orders
|
|
17
17
|
admiral.logger.debug("admiral before (#{graceful ? 'graceful' : 'hard'}) stop") if $DEBUG
|
18
18
|
end,
|
19
19
|
captains: {},
|
20
|
+
heartbeat: ->(admiral) do
|
21
|
+
admiral.logger.debug("admiral heartbeat") if $DEBUG
|
22
|
+
end,
|
20
23
|
post_fork: ->(admiral, captain) do
|
21
24
|
admiral.logger.debug("captain=#{captain.label} post-fork") if $DEBUG
|
22
25
|
end,
|
data/lib/navy/captain.rb
CHANGED
@@ -12,8 +12,8 @@ class Navy::Captain < Navy::Rank
|
|
12
12
|
# list of signals we care about and trap in admiral.
|
13
13
|
QUEUE_SIGS = [ :WINCH, :QUIT, :INT, :TERM, :USR1, :USR2, :HUP, :TTIN, :TTOU ]
|
14
14
|
|
15
|
-
attr_accessor :label, :captain_pid, :
|
16
|
-
attr_reader
|
15
|
+
attr_accessor :label, :captain_pid, :officer_count, :officer_job
|
16
|
+
attr_reader :admiral, :options
|
17
17
|
|
18
18
|
def initialize(admiral, label, config, options = {})
|
19
19
|
self.orig_stderr = $stderr.dup
|
@@ -70,6 +70,7 @@ class Navy::Captain < Navy::Rank
|
|
70
70
|
# avoid murdering workers after our master process (or the
|
71
71
|
# machine) comes out of suspend/hibernation
|
72
72
|
if (last_check + @timeout) >= (last_check = Time.now)
|
73
|
+
heartbeat.call(self) if heartbeat
|
73
74
|
sleep_time = murder_lazy_officers
|
74
75
|
logger.debug("would normally murder lazy officers") if $DEBUG
|
75
76
|
else
|
@@ -121,12 +122,15 @@ class Navy::Captain < Navy::Rank
|
|
121
122
|
# Terminates all captains, but does not exit admiral process
|
122
123
|
def stop(graceful = true)
|
123
124
|
before_stop.call(self, graceful) if before_stop
|
124
|
-
limit = Time.now +
|
125
|
-
until OFFICERS.empty? || Time.now > limit
|
125
|
+
limit = Time.now + patience
|
126
|
+
until OFFICERS.empty? || (n = Time.now) > limit
|
126
127
|
kill_each_officer(graceful ? :QUIT : :TERM)
|
127
128
|
sleep(0.1)
|
128
129
|
reap_all_officers
|
129
130
|
end
|
131
|
+
if n and n > limit
|
132
|
+
logger.debug "captain=#{label} patience exceeded by #{n - limit} seconds (limit #{patience} seconds)" if $DEBUG
|
133
|
+
end
|
130
134
|
kill_each_officer(:KILL)
|
131
135
|
after_stop.call(self, graceful) if after_stop
|
132
136
|
end
|
data/lib/navy/captain/orders.rb
CHANGED
@@ -13,8 +13,12 @@ class Navy::Captain::Orders < Navy::Orders
|
|
13
13
|
before_stop: ->(captain, graceful) do
|
14
14
|
captain.logger.debug("captain=#{captain.label} before (#{graceful ? 'graceful' : 'hard'}) stop") if $DEBUG
|
15
15
|
end,
|
16
|
+
heartbeat: ->(captain) do
|
17
|
+
captain.logger.debug("captain=#{captain.label} heartbeat") if $DEBUG
|
18
|
+
end,
|
16
19
|
officer_job: -> { trap(:QUIT) { exit }; trap(:TERM) { exit }; loop { sleep 1 } },
|
17
20
|
officer_count: 0,
|
21
|
+
patience: 30,
|
18
22
|
post_fork: ->(captain, officer) do
|
19
23
|
captain.logger.debug("(#{captain.label}) officer=#{officer.number} post-fork") if $DEBUG
|
20
24
|
end,
|
data/lib/navy/orders.rb
CHANGED
data/lib/navy/rank.rb
CHANGED
@@ -1,10 +1,28 @@
|
|
1
1
|
class Navy::Rank
|
2
2
|
|
3
|
+
# orders are configuration settings
|
3
4
|
attr_accessor :orders
|
4
5
|
|
5
|
-
|
6
|
+
## callbacks ##
|
7
|
+
attr_accessor :before_fork,
|
8
|
+
:before_stop,
|
9
|
+
:after_fork,
|
10
|
+
:after_stop,
|
11
|
+
:heartbeat,
|
12
|
+
:post_fork
|
13
|
+
|
14
|
+
## reexec ##
|
15
|
+
attr_accessor :reexec_pid
|
16
|
+
|
17
|
+
## respawn ##
|
18
|
+
attr_accessor :respawn_limit, :respawn_limit_seconds
|
19
|
+
|
20
|
+
## stderr/stdout ##
|
6
21
|
attr_reader :stdout_path, :stderr_path
|
7
|
-
attr_accessor :
|
22
|
+
attr_accessor :orig_stdout, :orig_stderr, :current_stdout, :current_stderr
|
23
|
+
|
24
|
+
## timeouts ##
|
25
|
+
attr_accessor :patience, :timeout
|
8
26
|
|
9
27
|
def logger
|
10
28
|
(@logger ||= orders[:logger]).tap do |log|
|
@@ -57,8 +75,6 @@ class Navy::Rank
|
|
57
75
|
redirect_io($stderr, path)
|
58
76
|
end
|
59
77
|
|
60
|
-
attr_accessor :timeout
|
61
|
-
|
62
78
|
private
|
63
79
|
|
64
80
|
# unlinks a PID file at given +path+ if it contains the current PID
|
data/lib/navy/speak.rb
CHANGED
@@ -30,6 +30,10 @@ class Navy::Speak
|
|
30
30
|
set_hook(:before_stop, block_given? ? block : args[0])
|
31
31
|
end
|
32
32
|
|
33
|
+
def heartbeat(*args, &block)
|
34
|
+
set_hook(:heartbeat, block_given? ? block : args[0], 1)
|
35
|
+
end
|
36
|
+
|
33
37
|
def logger(obj)
|
34
38
|
%w(debug info warn error fatal).each do |m|
|
35
39
|
obj.respond_to?(m) and next
|
@@ -39,6 +43,13 @@ class Navy::Speak
|
|
39
43
|
orders.set[:logger] = obj
|
40
44
|
end
|
41
45
|
|
46
|
+
def patience(seconds)
|
47
|
+
set_int(:patience, seconds, 3)
|
48
|
+
# POSIX says 31 days is the smallest allowed maximum timeout for select()
|
49
|
+
max = 30 * 60 * 60 * 24
|
50
|
+
orders.set[:patience] = seconds > max ? max : seconds
|
51
|
+
end
|
52
|
+
|
42
53
|
def pid(path); set_path(:pid, path); end
|
43
54
|
|
44
55
|
def post_fork(*args, &block)
|
data/lib/navy/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: navy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-03-
|
12
|
+
date: 2012-03-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: pry
|
16
|
-
requirement: &
|
16
|
+
requirement: &70241876400920 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70241876400920
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &70241876399140 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70241876399140
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rspec
|
38
|
-
requirement: &
|
38
|
+
requirement: &70241876397680 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 2.8.0
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70241876397680
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: kgio
|
49
|
-
requirement: &
|
49
|
+
requirement: &70241876396780 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: '2.6'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70241876396780
|
58
58
|
description: Ruby daemon inspired by Unicorn.
|
59
59
|
email:
|
60
60
|
- potatosaladx@gmail.com
|