navy 1.0.5 → 1.0.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|