rbg 1.0.2 → 1.1.0

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.
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