navy 1.0.6 → 1.0.7
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 +192 -32
- data/lib/navy/admiral.rb +2 -0
- data/lib/navy/admiral/orders.rb +6 -0
- data/lib/navy/captain.rb +2 -0
- data/lib/navy/captain/orders.rb +6 -0
- data/lib/navy/rank.rb +1 -1
- data/lib/navy/speak.rb +8 -0
- data/lib/navy/version.rb +1 -1
- metadata +9 -9
data/examples/navy.conf.rb
CHANGED
@@ -20,12 +20,52 @@ pid "/tmp/navy.pid"
|
|
20
20
|
# stderr_path "/tmp/navy-err.log"
|
21
21
|
# stdout_path "/tmp/navy-out.log"
|
22
22
|
|
23
|
+
# class Jacky
|
24
|
+
|
25
|
+
# SELF_PIPE = []
|
26
|
+
|
27
|
+
# def initialize
|
28
|
+
# init_self_pipe!
|
29
|
+
# end
|
30
|
+
|
31
|
+
# def call(officer)
|
32
|
+
# trap(:QUIT) { exit }
|
33
|
+
# trap(:TERM) { exit }
|
34
|
+
# # raise "HELLO"
|
35
|
+
# n = 0
|
36
|
+
# loop do
|
37
|
+
# puts "#{n} jack called (officer=#{officer.number}) pid: #{officer.officer_pid}"
|
38
|
+
# # Jack.logger.info "#{n} jack logger (officer=#{officer.number}) pid: #{officer.officer_pid}"
|
39
|
+
# # Navy.logger.info "START_CTX: #{START_CTX.inspect}"
|
40
|
+
# # Navy.logger.info "Navy::Admiral::CAPTAINS: #{Navy::Admiral::CAPTAINS.inspect}"
|
41
|
+
# # Navy.logger.info "Navy::Admiral::OFFICERS: #{Navy::Captain::OFFICERS.inspect}"
|
42
|
+
# sleep officer.number == 0 ? 0.5 : 1
|
43
|
+
# n += 1
|
44
|
+
# end
|
45
|
+
# end
|
46
|
+
|
47
|
+
# def logger
|
48
|
+
# @logger ||= Logger.new('/tmp/jack.log')
|
49
|
+
# end
|
50
|
+
|
51
|
+
# private
|
52
|
+
|
53
|
+
# def init_self_pipe!
|
54
|
+
|
55
|
+
# end
|
56
|
+
|
57
|
+
# end
|
58
|
+
|
23
59
|
module Jack
|
60
|
+
|
61
|
+
SELF_PIPE = []
|
62
|
+
|
24
63
|
extend self
|
25
64
|
|
26
65
|
def call(officer)
|
27
66
|
trap(:QUIT) { exit }
|
28
67
|
trap(:TERM) { exit }
|
68
|
+
|
29
69
|
# raise "HELLO"
|
30
70
|
n = 0
|
31
71
|
loop do
|
@@ -39,20 +79,20 @@ module Jack
|
|
39
79
|
end
|
40
80
|
end
|
41
81
|
|
42
|
-
def logger
|
43
|
-
require 'logger'
|
44
|
-
# @logger = nil if name
|
82
|
+
def logger
|
45
83
|
@logger ||= Logger.new('/tmp/jack.log')
|
46
84
|
end
|
47
85
|
|
86
|
+
def logger=(val)
|
87
|
+
@logger = val
|
88
|
+
end
|
89
|
+
|
48
90
|
def readers
|
49
|
-
@readers ||=
|
91
|
+
@readers ||= {}
|
50
92
|
end
|
51
93
|
|
52
94
|
def reader=(val)
|
53
|
-
|
54
|
-
readers.push(r)
|
55
|
-
end
|
95
|
+
@reader = val
|
56
96
|
end
|
57
97
|
|
58
98
|
def writer=(val)
|
@@ -66,6 +106,71 @@ module Jack
|
|
66
106
|
def writer
|
67
107
|
@writer
|
68
108
|
end
|
109
|
+
|
110
|
+
def main_reader=(val)
|
111
|
+
@main_reader = val
|
112
|
+
end
|
113
|
+
|
114
|
+
def main_writer=(val)
|
115
|
+
@main_writer = val
|
116
|
+
end
|
117
|
+
|
118
|
+
def main_reader
|
119
|
+
@main_reader
|
120
|
+
end
|
121
|
+
|
122
|
+
def main_writer
|
123
|
+
@main_writer
|
124
|
+
end
|
125
|
+
|
126
|
+
def threads
|
127
|
+
@threads ||= {}
|
128
|
+
end
|
129
|
+
|
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
|
+
|
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
|
+
|
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
|
69
174
|
end
|
70
175
|
|
71
176
|
captain :jack do
|
@@ -75,45 +180,100 @@ captain :jack do
|
|
75
180
|
|
76
181
|
preload do |captain|
|
77
182
|
captain.logger.warn "captain=#{captain.label} preload"
|
78
|
-
|
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 }
|
79
187
|
Jack.logger.info "preload"
|
80
|
-
|
81
|
-
Thread.new do
|
82
|
-
loop do
|
83
|
-
rs, ws = IO.select(Jack.readers, [], [], 1)
|
84
|
-
(rs || []).each do |r|
|
85
|
-
data = r.gets
|
86
|
-
next unless data
|
87
|
-
data.force_encoding("BINARY") if data.respond_to?(:force_encoding)
|
88
|
-
# ps, message = data.split(",", 2)
|
89
|
-
# color = colors[ps.split(".").first]
|
90
|
-
# info message, ps, color
|
91
|
-
# Jack.mutex.synchronize do
|
92
|
-
Jack.logger.info data.strip
|
93
|
-
# end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
188
|
+
Jack.start
|
97
189
|
end
|
98
190
|
|
99
191
|
before_fork do |captain, officer|
|
192
|
+
# Jack.main_thread(captain)
|
100
193
|
captain.logger.warn "captain=#{captain.label} before_fork"
|
101
194
|
officer.logger.warn "(#{captain.label}) officer=#{officer.number} before_fork"
|
102
|
-
|
103
|
-
|
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
|
104
201
|
end
|
105
202
|
|
106
203
|
after_fork do |captain, officer|
|
107
|
-
Jack.reader.close # we don't read
|
108
|
-
Jack.writer.sync = true
|
204
|
+
# Jack.reader.close # we don't read
|
205
|
+
# Jack.writer.sync = true
|
109
206
|
captain.logger.warn "captain=#{captain.label} after_fork"
|
110
207
|
officer.logger.warn "(#{captain.label}) officer=#{officer.number} after_fork"
|
111
|
-
$stdout.reopen Jack.writer
|
112
|
-
$stderr.reopen Jack.writer
|
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
|
+
|
222
|
+
after_stop do |captain, graceful|
|
223
|
+
Jack.stop if graceful
|
113
224
|
end
|
114
225
|
|
115
226
|
post_fork do |captain, officer|
|
116
|
-
Jack.writer.close
|
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
|
117
277
|
end
|
118
278
|
|
119
279
|
respawn_limit 15, 5
|
data/lib/navy/admiral.rb
CHANGED
@@ -131,6 +131,7 @@ class Navy::Admiral < Navy::Rank
|
|
131
131
|
|
132
132
|
# Terminates all captains, but does not exit admiral process
|
133
133
|
def stop(graceful = true)
|
134
|
+
before_stop.call(self, graceful) if before_stop
|
134
135
|
limit = Time.now + timeout
|
135
136
|
until CAPTAINS.empty? || Time.now > limit
|
136
137
|
kill_each_captain(graceful ? :QUIT : :TERM)
|
@@ -138,6 +139,7 @@ class Navy::Admiral < Navy::Rank
|
|
138
139
|
reap_all_captains
|
139
140
|
end
|
140
141
|
kill_each_captain(:KILL)
|
142
|
+
after_stop.call(self, graceful) if after_stop
|
141
143
|
end
|
142
144
|
|
143
145
|
private
|
data/lib/navy/admiral/orders.rb
CHANGED
@@ -4,12 +4,18 @@ class Navy::Admiral::Orders < Navy::Orders
|
|
4
4
|
after_fork: ->(admiral, captain) do
|
5
5
|
admiral.logger.info("captain=#{captain.label} spawned pid=#{$$}")
|
6
6
|
end,
|
7
|
+
after_stop: ->(admiral, graceful) do
|
8
|
+
admiral.logger.debug("admiral after (#{graceful ? 'graceful' : 'hard'}) stop") if $DEBUG
|
9
|
+
end,
|
7
10
|
before_fork: ->(admiral, captain) do
|
8
11
|
admiral.logger.info("captain=#{captain.label} spawning...")
|
9
12
|
end,
|
10
13
|
before_exec: ->(admiral) do
|
11
14
|
admiral.logger.info("forked child re-executing...")
|
12
15
|
end,
|
16
|
+
before_stop: ->(admiral, graceful) do
|
17
|
+
admiral.logger.debug("admiral before (#{graceful ? 'graceful' : 'hard'}) stop") if $DEBUG
|
18
|
+
end,
|
13
19
|
captains: {},
|
14
20
|
post_fork: ->(admiral, captain) do
|
15
21
|
admiral.logger.debug("captain=#{captain.label} post-fork") if $DEBUG
|
data/lib/navy/captain.rb
CHANGED
@@ -120,6 +120,7 @@ class Navy::Captain < Navy::Rank
|
|
120
120
|
|
121
121
|
# Terminates all captains, but does not exit admiral process
|
122
122
|
def stop(graceful = true)
|
123
|
+
before_stop.call(self, graceful) if before_stop
|
123
124
|
limit = Time.now + timeout
|
124
125
|
until OFFICERS.empty? || Time.now > limit
|
125
126
|
kill_each_officer(graceful ? :QUIT : :TERM)
|
@@ -127,6 +128,7 @@ class Navy::Captain < Navy::Rank
|
|
127
128
|
reap_all_officers
|
128
129
|
end
|
129
130
|
kill_each_officer(:KILL)
|
131
|
+
after_stop.call(self, graceful) if after_stop
|
130
132
|
end
|
131
133
|
|
132
134
|
private
|
data/lib/navy/captain/orders.rb
CHANGED
@@ -4,9 +4,15 @@ class Navy::Captain::Orders < Navy::Orders
|
|
4
4
|
after_fork: ->(captain, officer) do
|
5
5
|
captain.logger.info("(#{captain.label}) officer=#{officer.number} spawned pid=#{$$}")
|
6
6
|
end,
|
7
|
+
after_stop: ->(captain, graceful) do
|
8
|
+
captain.logger.debug("captain=#{captain.label} after (#{graceful ? 'graceful' : 'hard'}) stop") if $DEBUG
|
9
|
+
end,
|
7
10
|
before_fork: ->(captain, officer) do
|
8
11
|
captain.logger.info("(#{captain.label}) officer=#{officer.number} spawning...")
|
9
12
|
end,
|
13
|
+
before_stop: ->(captain, graceful) do
|
14
|
+
captain.logger.debug("captain=#{captain.label} before (#{graceful ? 'graceful' : 'hard'}) stop") if $DEBUG
|
15
|
+
end,
|
10
16
|
officer_job: -> { trap(:QUIT) { exit }; trap(:TERM) { exit }; loop { sleep 1 } },
|
11
17
|
officer_count: 0,
|
12
18
|
post_fork: ->(captain, officer) do
|
data/lib/navy/rank.rb
CHANGED
@@ -2,7 +2,7 @@ class Navy::Rank
|
|
2
2
|
|
3
3
|
attr_accessor :orders
|
4
4
|
|
5
|
-
attr_accessor :before_fork, :after_fork, :before_exec, :post_fork
|
5
|
+
attr_accessor :before_fork, :after_fork, :before_exec, :post_fork, :before_stop, :after_stop
|
6
6
|
attr_reader :stdout_path, :stderr_path
|
7
7
|
attr_accessor :reexec_pid, :orig_stdout, :orig_stderr, :current_stdout, :current_stderr
|
8
8
|
|
data/lib/navy/speak.rb
CHANGED
@@ -18,10 +18,18 @@ class Navy::Speak
|
|
18
18
|
set_hook(:after_fork, block_given? ? block : args[0])
|
19
19
|
end
|
20
20
|
|
21
|
+
def after_stop(*args, &block)
|
22
|
+
set_hook(:after_stop, block_given? ? block : args[0])
|
23
|
+
end
|
24
|
+
|
21
25
|
def before_fork(*args, &block)
|
22
26
|
set_hook(:before_fork, block_given? ? block : args[0])
|
23
27
|
end
|
24
28
|
|
29
|
+
def before_stop(*args, &block)
|
30
|
+
set_hook(:before_stop, block_given? ? block : args[0])
|
31
|
+
end
|
32
|
+
|
25
33
|
def logger(obj)
|
26
34
|
%w(debug info warn error fatal).each do |m|
|
27
35
|
obj.respond_to?(m) and next
|
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.0.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-03-06 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: pry
|
16
|
-
requirement: &
|
16
|
+
requirement: &70187979402440 !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: *70187979402440
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &70187979401840 !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: *70187979401840
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rspec
|
38
|
-
requirement: &
|
38
|
+
requirement: &70187979401100 !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: *70187979401100
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: kgio
|
49
|
-
requirement: &
|
49
|
+
requirement: &70187979400340 !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: *70187979400340
|
58
58
|
description: Ruby daemon inspired by Unicorn.
|
59
59
|
email:
|
60
60
|
- potatosaladx@gmail.com
|