rbg 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/rbg.rb +32 -19
  2. data/lib/rbg/config.rb +5 -0
  3. metadata +2 -2
data/lib/rbg.rb CHANGED
@@ -20,9 +20,9 @@ module Rbg
20
20
  # and then forking the worker processes.
21
21
  def start_parent
22
22
  # Record the PID of this parent in the Master
23
- self.child_processes << fork do
23
+ parent_pid = fork do
24
24
  # Clear the child process list as this fork doesn't have any children yet
25
- self.child_processes = Array.new
25
+ self.child_processes = Hash.new
26
26
 
27
27
  # Set the process name (Parent)
28
28
  $0="#{self.config.name}[Parent]"
@@ -61,22 +61,33 @@ module Rbg
61
61
  # We may add memory management code here in the future
62
62
  loop do
63
63
  sleep 2
64
- self.child_processes.dup.each do |p|
64
+ child_processes.dup.each do |id, opts|
65
65
  begin
66
- Process.getpgid( p )
66
+ Process.getpgid(opts[:pid])
67
67
  rescue Errno::ESRCH
68
- puts "Child process #{p} has died"
69
- child_processes.delete(p)
68
+ puts "Child process #{config.name}[#{id}] has died (from PID #{opts[:pid]})"
69
+ child_processes[id][:pid] = nil
70
+
71
+ if config.respawn_limit > opts[:respawns]
72
+ child_processes[id][:respawns] += 1
73
+ fork_worker(id)
74
+ else
75
+ child_processes.delete(id)
76
+ end
70
77
  end
71
78
  end
79
+
72
80
  if child_processes.empty?
73
81
  puts "All child processes died, exiting parent"
74
82
  Process.exit(0)
75
83
  end
76
84
  end
77
85
  end
86
+
87
+ # Store the PID for the parent
88
+ child_processes[0] = {:pid => parent_pid, :respawns => 0}
78
89
  # Ensure the new parent is detached
79
- Process.detach(self.child_processes.last)
90
+ Process.detach(parent_pid)
80
91
  end
81
92
 
82
93
  # Wrapper to fork multiple workers
@@ -87,10 +98,10 @@ module Rbg
87
98
  end
88
99
 
89
100
  # Fork a single worker
90
- def fork_worker(i)
101
+ def fork_worker(id)
91
102
  pid = fork do
92
103
  # Set process name
93
- $0="#{self.config.name}[#{i}]"
104
+ $0="#{config.name}[#{id}]"
94
105
 
95
106
  # Ending workers on INT is not useful or desirable
96
107
  Signal.trap('INT', proc {})
@@ -110,31 +121,33 @@ module Rbg
110
121
  end
111
122
 
112
123
  # Print some debug info and save the pid
113
- puts "Spawned '#{self.config.name}[#{i}]' as PID #{pid}"
124
+ puts "Spawned #{config.name}[#{id}] (with PID #{pid})"
114
125
  STDOUT.flush
115
126
 
116
127
  # Detach to eliminate Zombie processes later
117
128
  Process.detach(pid)
118
129
 
119
130
  # Save the worker PID into the Parent's child process list
120
- self.child_processes << pid
131
+ self.child_processes[id] ||= {}
132
+ self.child_processes[id][:pid] ||= pid
133
+ self.child_processes[id][:respawns] ||= 0
121
134
  end
122
135
 
123
136
  # Kill all child processes
124
137
  def kill_child_processes
125
138
  puts 'Killing child processes...'
126
139
  STDOUT.flush
127
- self.child_processes.each do |p|
128
- puts "Killing: #{p}"
140
+ self.child_processes.each do |id, opts|
141
+ puts "Killing #{config.name}[#{id}] (with PID #{opts[:pid]})"
129
142
  STDOUT.flush
130
143
  begin
131
- Process.kill('TERM', p)
144
+ Process.kill('TERM', opts[:pid])
132
145
  rescue
133
146
  puts "Process already gone away"
134
147
  end
135
148
  end
136
149
  # Clear the child process list because we just killed them all
137
- self.child_processes = Array.new
150
+ self.child_processes = Hash.new
138
151
  end
139
152
 
140
153
  # This is the master process, it spawns some workers then loops
@@ -186,11 +199,11 @@ module Rbg
186
199
  restart_needed = false
187
200
  end
188
201
 
189
- self.child_processes.each do |p|
202
+ self.child_processes.each do |id, opts|
190
203
  begin
191
- Process.getpgid( p )
204
+ Process.getpgid(opts[:pid])
192
205
  rescue Errno::ESRCH
193
- puts "Parent process #{p} has died, exiting master"
206
+ puts "Parent process #{config.name}[#{id}] has died (from PID #{opts[:pid]}), exiting master"
194
207
  Process.exit(0)
195
208
  end
196
209
  end
@@ -229,7 +242,7 @@ module Rbg
229
242
  end
230
243
 
231
244
  # Initialize child process array
232
- self.child_processes = Array.new
245
+ self.child_processes = Hash.new
233
246
 
234
247
  if options[:background]
235
248
  # Fork the master control process and return to a shell
data/lib/rbg/config.rb CHANGED
@@ -7,6 +7,7 @@ module Rbg
7
7
  attr_accessor :log_path
8
8
  attr_accessor :pid_path
9
9
  attr_accessor :workers
10
+ attr_accessor :respawn_limit
10
11
 
11
12
  def root
12
13
  @root || File.expand_path('./')
@@ -24,6 +25,10 @@ module Rbg
24
25
  block_given? ? @script = block : @script
25
26
  end
26
27
 
28
+ def respawn_limit
29
+ @respawn_limit || 0
30
+ end
31
+
27
32
  def before_fork(&block)
28
33
  block_given? ? @before_fork = block : @before_fork
29
34
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbg
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-02-10 00:00:00.000000000 Z
12
+ date: 2014-02-21 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description:
15
15
  email: charlie@atechmedia.com