rbg 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/rbg.rb +25 -19
- data/lib/rbg/config.rb +7 -0
- metadata +23 -11
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 951b145c93a3b790e30bdafc6115aa1baed85968
|
4
|
+
data.tar.gz: 50a5213e22f764ac53430cadc484df88ef760652
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 70aade66d0e8606dae64491d94e01259770f71b6f29c3af33f0680b9b28ca93ddb7976e100c3591b5212de22496f5ca05cfc3eb484a8772bcb2986562ff50e85
|
7
|
+
data.tar.gz: 8fb2c16612a80ace8068b6886eed6bc3954df4d1557bdb4fc73d1fe9bf90604dd522caf4774dae0004662249faeaf8a9772aa4dfdc1c69f89ed70798d5089a9c
|
data/lib/rbg.rb
CHANGED
@@ -16,6 +16,11 @@ module Rbg
|
|
16
16
|
@config ||= Rbg::Config.new
|
17
17
|
end
|
18
18
|
|
19
|
+
# Return a logger object for this application
|
20
|
+
def logger
|
21
|
+
self.config.logger
|
22
|
+
end
|
23
|
+
|
19
24
|
# Creates a 'parent' process. This is responsible for executing 'before_fork'
|
20
25
|
# and then forking the worker processes.
|
21
26
|
def start_parent
|
@@ -28,7 +33,7 @@ module Rbg
|
|
28
33
|
$0="#{self.config.name}[Parent]"
|
29
34
|
|
30
35
|
# Debug information
|
31
|
-
|
36
|
+
logger.info "New parent process: #{Process.pid}"
|
32
37
|
STDOUT.flush
|
33
38
|
|
34
39
|
# Run the before_fork function
|
@@ -42,7 +47,7 @@ module Rbg
|
|
42
47
|
# If we get a TERM, send the existing workers a TERM then exit
|
43
48
|
Signal.trap("TERM", proc {
|
44
49
|
# Debug output
|
45
|
-
|
50
|
+
logger.info "Parent got a TERM."
|
46
51
|
STDOUT.flush
|
47
52
|
|
48
53
|
# Send TERM to workers
|
@@ -70,27 +75,27 @@ module Rbg
|
|
70
75
|
# Lookup the memory usge for this PID
|
71
76
|
memory_usage = `ps -o rss= -p #{opts[:pid]}`.strip.to_i / 1024
|
72
77
|
if memory_usage > config.memory_limit
|
73
|
-
|
78
|
+
logger.info "#{self.config.name}[#{id}] is using #{memory_usage}MB of memory (limit: #{config.memory_limit}MB). It will be killed."
|
74
79
|
kill_child_process(id)
|
75
80
|
end
|
76
81
|
end
|
77
82
|
|
78
83
|
rescue Errno::ESRCH
|
79
|
-
|
84
|
+
logger.info "Child process #{config.name}[#{id}] has died (from PID #{opts[:pid]})"
|
80
85
|
child_processes[id][:pid] = nil
|
81
86
|
|
82
87
|
if config.respawn
|
83
88
|
if opts[:started_at] > Time.now - config.respawn_limits[1]
|
84
89
|
if opts[:respawns] >= config.respawn_limits[0]
|
85
|
-
|
90
|
+
logger.info "Process #{config.name}[#{id}] has instantly respawned #{opts[:respawns]} times. It won't be respawned again."
|
86
91
|
child_processes.delete(id)
|
87
92
|
else
|
88
|
-
|
93
|
+
logger.info "Process has died within #{config.respawn_limits[1]}s of the last spawn."
|
89
94
|
child_processes[id][:respawns] += 1
|
90
95
|
fork_worker(id)
|
91
96
|
end
|
92
97
|
else
|
93
|
-
|
98
|
+
logger.info "Process was started more than #{config.respawn_limits[1]}s since the last spawn. Resetting spawn counter"
|
94
99
|
child_processes[id][:respawns] = 0
|
95
100
|
fork_worker(id)
|
96
101
|
end
|
@@ -101,7 +106,7 @@ module Rbg
|
|
101
106
|
end
|
102
107
|
|
103
108
|
if child_processes.empty?
|
104
|
-
|
109
|
+
logger.info "All child processes died, exiting parent"
|
105
110
|
Process.exit(0)
|
106
111
|
end
|
107
112
|
end
|
@@ -144,7 +149,7 @@ module Rbg
|
|
144
149
|
end
|
145
150
|
|
146
151
|
# Print some debug info and save the pid
|
147
|
-
|
152
|
+
logger.info "Spawned #{config.name}[#{id}] (with PID #{pid})"
|
148
153
|
STDOUT.flush
|
149
154
|
|
150
155
|
# Detach to eliminate Zombie processes later
|
@@ -160,19 +165,19 @@ module Rbg
|
|
160
165
|
# Kill a given child process
|
161
166
|
def kill_child_process(id)
|
162
167
|
if opts = self.child_processes[id]
|
163
|
-
|
168
|
+
logger.info "Killing #{config.name}[#{id}] (with PID #{opts[:pid]})"
|
164
169
|
STDOUT.flush
|
165
170
|
begin
|
166
171
|
Process.kill('TERM', opts[:pid])
|
167
172
|
rescue
|
168
|
-
|
173
|
+
logger.info "Process already gone away"
|
169
174
|
end
|
170
175
|
end
|
171
176
|
end
|
172
177
|
|
173
178
|
# Kill all child processes
|
174
179
|
def kill_child_processes
|
175
|
-
|
180
|
+
logger.info 'Killing child processes...'
|
176
181
|
STDOUT.flush
|
177
182
|
self.child_processes.keys.each { |id| kill_child_process(id) }
|
178
183
|
self.child_processes = Hash.new
|
@@ -181,7 +186,7 @@ module Rbg
|
|
181
186
|
# This is the master process, it spawns some workers then loops
|
182
187
|
def master_process
|
183
188
|
# Log the master PID
|
184
|
-
|
189
|
+
logger.info "New master process: #{Process.pid}"
|
185
190
|
STDOUT.flush
|
186
191
|
|
187
192
|
# Set the process name
|
@@ -196,13 +201,13 @@ module Rbg
|
|
196
201
|
|
197
202
|
# If we get a USR1, set this process as waiting for a restart
|
198
203
|
Signal.trap("USR1", proc {
|
199
|
-
|
204
|
+
logger.info "Master got a USR1."
|
200
205
|
restart_needed = true
|
201
206
|
})
|
202
207
|
|
203
208
|
# If we get a TERM, send the existing workers a TERM before bowing out
|
204
209
|
Signal.trap("TERM", proc {
|
205
|
-
|
210
|
+
logger.info "Master got a TERM."
|
206
211
|
STDOUT.flush
|
207
212
|
kill_child_processes
|
208
213
|
Process.exit(0)
|
@@ -210,7 +215,7 @@ module Rbg
|
|
210
215
|
|
211
216
|
# INT is useful for when we don't want to background
|
212
217
|
Signal.trap("INT", proc {
|
213
|
-
|
218
|
+
logger.info "Master got an INT."
|
214
219
|
STDOUT.flush
|
215
220
|
kill_child_processes
|
216
221
|
Process.exit(0)
|
@@ -231,7 +236,7 @@ module Rbg
|
|
231
236
|
begin
|
232
237
|
Process.getpgid(opts[:pid])
|
233
238
|
rescue Errno::ESRCH
|
234
|
-
|
239
|
+
logger.info "Parent process #{config.name}[#{id}] has died (from PID #{opts[:pid]}), exiting master"
|
235
240
|
Process.exit(0)
|
236
241
|
end
|
237
242
|
end
|
@@ -295,9 +300,10 @@ module Rbg
|
|
295
300
|
File.open(self.config.pid_path, 'w') {|f| f.write(master_pid) }
|
296
301
|
end
|
297
302
|
|
298
|
-
|
303
|
+
logger.info "Master started as PID #{master_pid}"
|
299
304
|
else
|
300
|
-
# Run using existing STDIN / STDOUT
|
305
|
+
# Run using existing STDIN / STDOUT and set logger to use use STDOUT regardless
|
306
|
+
self.config.logger = MonoLogger.new(STDOUT)
|
301
307
|
self.master_process
|
302
308
|
end
|
303
309
|
end
|
data/lib/rbg/config.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'mono_logger'
|
2
|
+
|
1
3
|
module Rbg
|
2
4
|
class Config
|
3
5
|
|
@@ -10,6 +12,7 @@ module Rbg
|
|
10
12
|
attr_accessor :respawn
|
11
13
|
attr_accessor :respawn_limits
|
12
14
|
attr_accessor :memory_limit
|
15
|
+
attr_accessor :logger
|
13
16
|
|
14
17
|
def root
|
15
18
|
@root || File.expand_path('./')
|
@@ -47,5 +50,9 @@ module Rbg
|
|
47
50
|
block_given? ? @after_fork = block : @after_fork
|
48
51
|
end
|
49
52
|
|
53
|
+
def logger
|
54
|
+
@logger ||= MonoLogger.new(self.log_path)
|
55
|
+
end
|
56
|
+
|
50
57
|
end
|
51
58
|
end
|
metadata
CHANGED
@@ -1,16 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
5
|
-
prerelease:
|
4
|
+
version: 1.3.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Charlie Smurthwaite
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2014-
|
13
|
-
dependencies:
|
11
|
+
date: 2014-05-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: mono_logger
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.1'
|
14
27
|
description:
|
15
28
|
email: charlie@atechmedia.com
|
16
29
|
executables:
|
@@ -19,31 +32,30 @@ extensions: []
|
|
19
32
|
extra_rdoc_files: []
|
20
33
|
files:
|
21
34
|
- bin/rbg
|
22
|
-
- lib/rbg/config.rb
|
23
35
|
- lib/rbg.rb
|
36
|
+
- lib/rbg/config.rb
|
24
37
|
homepage: http://www.atechmedia.com
|
25
38
|
licenses: []
|
39
|
+
metadata: {}
|
26
40
|
post_install_message:
|
27
41
|
rdoc_options: []
|
28
42
|
require_paths:
|
29
43
|
- lib
|
30
44
|
required_ruby_version: !ruby/object:Gem::Requirement
|
31
|
-
none: false
|
32
45
|
requirements:
|
33
|
-
- -
|
46
|
+
- - ">="
|
34
47
|
- !ruby/object:Gem::Version
|
35
48
|
version: '0'
|
36
49
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
-
none: false
|
38
50
|
requirements:
|
39
|
-
- -
|
51
|
+
- - ">="
|
40
52
|
- !ruby/object:Gem::Version
|
41
53
|
version: '0'
|
42
54
|
requirements: []
|
43
55
|
rubyforge_project:
|
44
|
-
rubygems_version:
|
56
|
+
rubygems_version: 2.2.0
|
45
57
|
signing_key:
|
46
|
-
specification_version:
|
58
|
+
specification_version: 4
|
47
59
|
summary: Ruby Backgrounder allows multiple copies of ruby scripts to be run in the
|
48
60
|
background and restarted
|
49
61
|
test_files: []
|