navy 1.0.5 → 1.0.6
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 +97 -16
- data/lib/navy.rb +2 -1
- data/lib/navy/admiral.rb +5 -0
- data/lib/navy/admiral/orders.rb +3 -0
- data/lib/navy/captain.rb +8 -2
- data/lib/navy/captain/orders.rb +3 -0
- data/lib/navy/rank.rb +14 -5
- data/lib/navy/scoped_logger.rb +74 -0
- data/lib/navy/speak.rb +4 -0
- data/lib/navy/version.rb +1 -1
- metadata +11 -10
data/examples/navy.conf.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
preload do |admiral|
|
2
|
+
# require 'rainbow'
|
2
3
|
admiral.logger.warn "admiral preload"
|
3
4
|
end
|
4
5
|
|
@@ -8,7 +9,7 @@ before_fork do |admiral, captain|
|
|
8
9
|
end
|
9
10
|
|
10
11
|
after_fork do |admiral, captain|
|
11
|
-
|
12
|
+
captain.logger.warn "admiral (#{captain.label}) after_fork"
|
12
13
|
captain.logger.warn "captain=#{captain.label} after_fork"
|
13
14
|
end
|
14
15
|
|
@@ -19,41 +20,119 @@ pid "/tmp/navy.pid"
|
|
19
20
|
# stderr_path "/tmp/navy-err.log"
|
20
21
|
# stdout_path "/tmp/navy-out.log"
|
21
22
|
|
23
|
+
module Jack
|
24
|
+
extend self
|
25
|
+
|
26
|
+
def call(officer)
|
27
|
+
trap(:QUIT) { exit }
|
28
|
+
trap(:TERM) { exit }
|
29
|
+
# raise "HELLO"
|
30
|
+
n = 0
|
31
|
+
loop do
|
32
|
+
puts "#{n} jack called (officer=#{officer.number}) pid: #{officer.officer_pid}"
|
33
|
+
# Jack.logger.info "#{n} jack logger (officer=#{officer.number}) pid: #{officer.officer_pid}"
|
34
|
+
# Navy.logger.info "START_CTX: #{START_CTX.inspect}"
|
35
|
+
# Navy.logger.info "Navy::Admiral::CAPTAINS: #{Navy::Admiral::CAPTAINS.inspect}"
|
36
|
+
# Navy.logger.info "Navy::Admiral::OFFICERS: #{Navy::Captain::OFFICERS.inspect}"
|
37
|
+
sleep officer.number == 0 ? 0.5 : 1
|
38
|
+
n += 1
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def logger#(name = nil)
|
43
|
+
require 'logger'
|
44
|
+
# @logger = nil if name
|
45
|
+
@logger ||= Logger.new('/tmp/jack.log')
|
46
|
+
end
|
47
|
+
|
48
|
+
def readers
|
49
|
+
@readers ||= []
|
50
|
+
end
|
51
|
+
|
52
|
+
def reader=(val)
|
53
|
+
(@reader = val).tap do |r|
|
54
|
+
readers.push(r)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def writer=(val)
|
59
|
+
@writer = val
|
60
|
+
end
|
61
|
+
|
62
|
+
def reader
|
63
|
+
@reader
|
64
|
+
end
|
65
|
+
|
66
|
+
def writer
|
67
|
+
@writer
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
22
71
|
captain :jack do
|
23
72
|
|
24
73
|
stderr_path "/tmp/navy-jack-err.log"
|
25
|
-
stdout_path "/tmp/navy-jack-out.log"
|
74
|
+
# stdout_path "/tmp/navy-jack-out.log"
|
26
75
|
|
27
76
|
preload do |captain|
|
28
77
|
captain.logger.warn "captain=#{captain.label} preload"
|
78
|
+
# Jack.mutex.synchronize do
|
79
|
+
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
|
29
97
|
end
|
30
98
|
|
31
99
|
before_fork do |captain, officer|
|
32
100
|
captain.logger.warn "captain=#{captain.label} before_fork"
|
33
101
|
officer.logger.warn "(#{captain.label}) officer=#{officer.number} before_fork"
|
102
|
+
Jack.reader, Jack.writer = IO.pipe
|
103
|
+
Jack.reader.sync = true
|
34
104
|
end
|
35
105
|
|
36
106
|
after_fork do |captain, officer|
|
107
|
+
Jack.reader.close # we don't read
|
108
|
+
Jack.writer.sync = true
|
37
109
|
captain.logger.warn "captain=#{captain.label} after_fork"
|
38
110
|
officer.logger.warn "(#{captain.label}) officer=#{officer.number} after_fork"
|
111
|
+
$stdout.reopen Jack.writer
|
112
|
+
$stderr.reopen Jack.writer
|
113
|
+
end
|
114
|
+
|
115
|
+
post_fork do |captain, officer|
|
116
|
+
Jack.writer.close
|
39
117
|
end
|
40
118
|
|
41
119
|
respawn_limit 15, 5
|
42
120
|
|
43
|
-
officers
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
121
|
+
officers 4, Jack
|
122
|
+
# officers 2 do |officer|
|
123
|
+
# trap(:QUIT) { exit }
|
124
|
+
# trap(:TERM) { exit }
|
125
|
+
# # raise "HELLO"
|
126
|
+
# n = 0
|
127
|
+
# loop do
|
128
|
+
# Navy.logger.info "#{n} jack called (officer=#{officer.number}) pid: #{officer.officer_pid}"
|
129
|
+
# # Navy.logger.info "START_CTX: #{START_CTX.inspect}"
|
130
|
+
# # Navy.logger.info "Navy::Admiral::CAPTAINS: #{Navy::Admiral::CAPTAINS.inspect}"
|
131
|
+
# # Navy.logger.info "Navy::Admiral::OFFICERS: #{Navy::Captain::OFFICERS.inspect}"
|
132
|
+
# sleep 1
|
133
|
+
# n += 1
|
134
|
+
# end
|
135
|
+
# end
|
57
136
|
|
58
137
|
end
|
59
138
|
|
@@ -61,6 +140,8 @@ captain :blackbeard do
|
|
61
140
|
|
62
141
|
pid "/tmp/navy-blackbeard.pid"
|
63
142
|
|
143
|
+
# stderr_path '/tmp/navy-blackbeard-err.log'
|
144
|
+
|
64
145
|
officers 5 do
|
65
146
|
trap(:QUIT) { exit }; trap(:TERM) { exit }; loop { sleep 1 }
|
66
147
|
end
|
data/lib/navy.rb
CHANGED
@@ -11,7 +11,7 @@ require 'logger'
|
|
11
11
|
module Navy
|
12
12
|
extend self
|
13
13
|
def logger
|
14
|
-
@logger ||= Logger.new($stderr)
|
14
|
+
@logger ||= Navy::ScopedLogger.new(Logger.new($stderr))
|
15
15
|
end
|
16
16
|
|
17
17
|
def log_error(logger, prefix, exc)
|
@@ -21,6 +21,7 @@ module Navy
|
|
21
21
|
exc.backtrace.each { |line| logger.error(line) }
|
22
22
|
end
|
23
23
|
end
|
24
|
+
require 'navy/scoped_logger'
|
24
25
|
require 'navy/util'
|
25
26
|
require 'navy/orders'
|
26
27
|
require 'navy/rank'
|
data/lib/navy/admiral.rb
CHANGED
@@ -30,6 +30,8 @@ class Navy::Admiral < Navy::Rank
|
|
30
30
|
attr_reader :options
|
31
31
|
|
32
32
|
def initialize(options = {})
|
33
|
+
self.orig_stderr = $stderr.dup
|
34
|
+
self.orig_stdout = $stdout.dup
|
33
35
|
self.reexec_pid = 0
|
34
36
|
|
35
37
|
@options = options.dup
|
@@ -243,7 +245,10 @@ class Navy::Admiral < Navy::Rank
|
|
243
245
|
CAPTAINS[pid] = captain
|
244
246
|
RESPAWNS[label] ||= []
|
245
247
|
RESPAWNS[label].push(Time.now)
|
248
|
+
captain.captain_pid = pid
|
249
|
+
post_fork.call(self, captain) if post_fork
|
246
250
|
else
|
251
|
+
captain.orders.give!(captain, only: [ :stderr_path, :stdout_path ])
|
247
252
|
after_fork.call(self, captain) if after_fork
|
248
253
|
captain.start.join
|
249
254
|
exit
|
data/lib/navy/admiral/orders.rb
CHANGED
@@ -11,6 +11,9 @@ class Navy::Admiral::Orders < Navy::Orders
|
|
11
11
|
admiral.logger.info("forked child re-executing...")
|
12
12
|
end,
|
13
13
|
captains: {},
|
14
|
+
post_fork: ->(admiral, captain) do
|
15
|
+
admiral.logger.debug("captain=#{captain.label} post-fork") if $DEBUG
|
16
|
+
end,
|
14
17
|
preload: ->(admiral) do
|
15
18
|
admiral.logger.info("admiral preloading...")
|
16
19
|
end,
|
data/lib/navy/captain.rb
CHANGED
@@ -16,6 +16,9 @@ class Navy::Captain < Navy::Rank
|
|
16
16
|
attr_reader :admiral, :options
|
17
17
|
|
18
18
|
def initialize(admiral, label, config, options = {})
|
19
|
+
self.orig_stderr = $stderr.dup
|
20
|
+
self.orig_stdout = $stdout.dup
|
21
|
+
|
19
22
|
@options = options.dup
|
20
23
|
@options[:use_defaults] = true
|
21
24
|
@options[:config_file] = config
|
@@ -32,11 +35,12 @@ class Navy::Captain < Navy::Rank
|
|
32
35
|
end
|
33
36
|
|
34
37
|
def start
|
35
|
-
orders.give!(self, only: [ :stderr_path, :stdout_path ])
|
36
38
|
init_self_pipe!
|
37
39
|
QUEUE_SIGS.each do |sig|
|
38
40
|
trap(sig) do
|
39
|
-
|
41
|
+
if $DEBUG
|
42
|
+
logger.debug "captain[#{label}] received #{sig}"
|
43
|
+
end
|
40
44
|
SIG_QUEUE << sig
|
41
45
|
awaken_captain
|
42
46
|
end
|
@@ -187,6 +191,8 @@ class Navy::Captain < Navy::Rank
|
|
187
191
|
OFFICERS[pid] = officer
|
188
192
|
RESPAWNS[n] ||= []
|
189
193
|
RESPAWNS[n].push(Time.now)
|
194
|
+
officer.officer_pid = pid
|
195
|
+
post_fork.call(self, officer) if post_fork
|
190
196
|
else
|
191
197
|
after_fork.call(self, officer) if after_fork
|
192
198
|
officer.start
|
data/lib/navy/captain/orders.rb
CHANGED
@@ -9,6 +9,9 @@ class Navy::Captain::Orders < Navy::Orders
|
|
9
9
|
end,
|
10
10
|
officer_job: -> { trap(:QUIT) { exit }; trap(:TERM) { exit }; loop { sleep 1 } },
|
11
11
|
officer_count: 0,
|
12
|
+
post_fork: ->(captain, officer) do
|
13
|
+
captain.logger.debug("(#{captain.label}) officer=#{officer.number} post-fork") if $DEBUG
|
14
|
+
end,
|
12
15
|
preload: ->(captain) do
|
13
16
|
captain.logger.info("captain=#{captain.label} preloading...")
|
14
17
|
end,
|
data/lib/navy/rank.rb
CHANGED
@@ -2,11 +2,14 @@ class Navy::Rank
|
|
2
2
|
|
3
3
|
attr_accessor :orders
|
4
4
|
|
5
|
-
attr_accessor :before_fork, :after_fork, :before_exec
|
6
|
-
|
5
|
+
attr_accessor :before_fork, :after_fork, :before_exec, :post_fork
|
6
|
+
attr_reader :stdout_path, :stderr_path
|
7
|
+
attr_accessor :reexec_pid, :orig_stdout, :orig_stderr, :current_stdout, :current_stderr
|
7
8
|
|
8
9
|
def logger
|
9
|
-
@logger ||= orders[:logger]
|
10
|
+
(@logger ||= orders[:logger]).tap do |log|
|
11
|
+
log.scope = self #if log.respond_to?(:scope=)
|
12
|
+
end
|
10
13
|
end
|
11
14
|
attr_writer :logger
|
12
15
|
|
@@ -45,8 +48,14 @@ class Navy::Rank
|
|
45
48
|
|
46
49
|
attr_accessor :preload
|
47
50
|
|
48
|
-
def stdout_path=(path)
|
49
|
-
|
51
|
+
def stdout_path=(path)
|
52
|
+
@stdout_path = path
|
53
|
+
redirect_io($stdout, path)
|
54
|
+
end
|
55
|
+
def stderr_path=(path)
|
56
|
+
@stderr_path = path
|
57
|
+
redirect_io($stderr, path)
|
58
|
+
end
|
50
59
|
|
51
60
|
attr_accessor :timeout
|
52
61
|
|
@@ -0,0 +1,74 @@
|
|
1
|
+
class Navy::ScopedLogger
|
2
|
+
|
3
|
+
attr_accessor :logger, :scope
|
4
|
+
|
5
|
+
def initialize(logger, scope = nil)
|
6
|
+
@logger, @scope = logger, scope
|
7
|
+
end
|
8
|
+
|
9
|
+
def add(*args, &block)
|
10
|
+
scoped(:add, *args, &block)
|
11
|
+
end
|
12
|
+
|
13
|
+
def debug(*args, &block)
|
14
|
+
scoped(:debug, *args, &block)
|
15
|
+
end
|
16
|
+
|
17
|
+
def info(*args, &block)
|
18
|
+
scoped(:info, *args, &block)
|
19
|
+
end
|
20
|
+
|
21
|
+
def warn(*args, &block)
|
22
|
+
scoped(:warn, *args, &block)
|
23
|
+
end
|
24
|
+
|
25
|
+
def error(*args, &block)
|
26
|
+
scoped(:error, *args, &block)
|
27
|
+
end
|
28
|
+
|
29
|
+
def fatal(*args, &block)
|
30
|
+
scoped(:fatal, *args, &block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def respond_to?(*args)
|
34
|
+
@logger.respond_to?(*args)
|
35
|
+
end
|
36
|
+
|
37
|
+
protected
|
38
|
+
|
39
|
+
def method_missing(name, *args, &block)
|
40
|
+
@logger.__send__(name, *args, &block)
|
41
|
+
end
|
42
|
+
|
43
|
+
def scoped(name, *args, &block)
|
44
|
+
start_scope!
|
45
|
+
retval = @logger.__send__(name, *args, &block)
|
46
|
+
stop_scope!
|
47
|
+
return retval
|
48
|
+
end
|
49
|
+
|
50
|
+
def start_scope!
|
51
|
+
return unless scope
|
52
|
+
scope.current_stdout = $stdout.dup
|
53
|
+
scope.current_stderr = $stderr.dup
|
54
|
+
if scope.stderr_path
|
55
|
+
scope.stderr_path = scope.stderr_path
|
56
|
+
else
|
57
|
+
$stderr.reopen scope.orig_stderr
|
58
|
+
end
|
59
|
+
if scope.stdout_path
|
60
|
+
scope.stdout_path = scope.stdout_path
|
61
|
+
else
|
62
|
+
$stdout.reopen scope.orig_stdout
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def stop_scope!
|
67
|
+
return unless scope
|
68
|
+
return unless scope.current_stderr and scope.current_stdout
|
69
|
+
$stdout.reopen scope.current_stdout
|
70
|
+
$stderr.reopen scope.current_stderr
|
71
|
+
scope.current_stderr = scope.current_stdout = nil
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
data/lib/navy/speak.rb
CHANGED
@@ -33,6 +33,10 @@ class Navy::Speak
|
|
33
33
|
|
34
34
|
def pid(path); set_path(:pid, path); end
|
35
35
|
|
36
|
+
def post_fork(*args, &block)
|
37
|
+
set_hook(:post_fork, block_given? ? block : args[0])
|
38
|
+
end
|
39
|
+
|
36
40
|
def preload(*args, &block)
|
37
41
|
set_hook(:preload, block_given? ? block : args[0], 1)
|
38
42
|
end
|
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.6
|
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-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: pry
|
16
|
-
requirement: &
|
16
|
+
requirement: &70207025737040 !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: *70207025737040
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &70207025736560 !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: *70207025736560
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rspec
|
38
|
-
requirement: &
|
38
|
+
requirement: &70207025735780 !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: *70207025735780
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: kgio
|
49
|
-
requirement: &
|
49
|
+
requirement: &70207025735040 !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: *70207025735040
|
58
58
|
description: Ruby daemon inspired by Unicorn.
|
59
59
|
email:
|
60
60
|
- potatosaladx@gmail.com
|
@@ -80,6 +80,7 @@ files:
|
|
80
80
|
- lib/navy/officer.rb
|
81
81
|
- lib/navy/orders.rb
|
82
82
|
- lib/navy/rank.rb
|
83
|
+
- lib/navy/scoped_logger.rb
|
83
84
|
- lib/navy/ship.rb
|
84
85
|
- lib/navy/speak.rb
|
85
86
|
- lib/navy/util.rb
|