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.
@@ -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#(name = nil)
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
- (@reader = val).tap do |r|
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
- # Jack.mutex.synchronize do
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
- # end
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
- Jack.reader, Jack.writer = IO.pipe
103
- Jack.reader.sync = true
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
 
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Navy
2
- VERSION = "1.0.6"
2
+ VERSION = "1.0.7"
3
3
  end
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.6
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: &70207025737040 !ruby/object:Gem::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: *70207025737040
24
+ version_requirements: *70187979402440
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &70207025736560 !ruby/object:Gem::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: *70207025736560
35
+ version_requirements: *70187979401840
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &70207025735780 !ruby/object:Gem::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: *70207025735780
46
+ version_requirements: *70187979401100
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: kgio
49
- requirement: &70207025735040 !ruby/object:Gem::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: *70207025735040
57
+ version_requirements: *70187979400340
58
58
  description: Ruby daemon inspired by Unicorn.
59
59
  email:
60
60
  - potatosaladx@gmail.com