xpool 0.10.0 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog.txt +20 -0
- data/lib/xpool/process.rb +18 -9
- data/lib/xpool/version.rb +1 -1
- data/test/support/io_writer.rb +16 -4
- data/test/support/raiser.rb +5 -0
- data/test/xpool_process_test.rb +10 -0
- metadata +4 -4
data/ChangeLog.txt
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
== HEAD
|
2
|
+
- no longer log from trap(…) block.
|
3
|
+
the logger cannot log from within a trap block on Ruby2, so I've removed
|
4
|
+
logging when a subprocess gets a request to shutdown.
|
5
|
+
|
6
|
+
- call 'setup' on unit of work if defined.
|
7
|
+
'setup', if defined by a unit of work, is called just before a unit of work
|
8
|
+
is executed for the first time… useful if you need to create an environment
|
9
|
+
for the subprocess to operate in.
|
10
|
+
|
11
|
+
- resize & resize! no longer accepts a Range.
|
12
|
+
deprecated in the last release, support for a Range to either resize or
|
13
|
+
resize! is completely removed in this release. Please use a Fixnum instead.
|
14
|
+
|
15
|
+
== v0.10.1
|
16
|
+
- Restarted subprocesses inherit the message queue of their predecessor.
|
17
|
+
when a failed subprocess is restarted its message queue is inherited by its
|
18
|
+
replacement. Any messages it had waiting will be processed by the replacement
|
19
|
+
process.
|
20
|
+
|
1
21
|
== v0.10.0
|
2
22
|
- default to two subprocesses if CPU core count cannot be guessed.
|
3
23
|
Which is change from the old default of five.
|
data/lib/xpool/process.rb
CHANGED
@@ -4,6 +4,7 @@ class XPool::Process
|
|
4
4
|
# Returns an instance of XPool::Process
|
5
5
|
#
|
6
6
|
def initialize
|
7
|
+
reset
|
7
8
|
@id = spawn
|
8
9
|
end
|
9
10
|
|
@@ -115,25 +116,32 @@ class XPool::Process
|
|
115
116
|
@states[:backtrace]
|
116
117
|
end
|
117
118
|
|
119
|
+
#
|
120
|
+
# Restart the process. The current process shuts down(gracefully) and a new
|
121
|
+
# process replaces it. If the current process has failed the new process will
|
122
|
+
# inherit its message queue.
|
118
123
|
#
|
119
124
|
# @return [Fixnum]
|
120
125
|
# Returns the process ID of the new process.
|
121
126
|
#
|
122
127
|
def restart
|
123
|
-
|
128
|
+
_shutdown 'SIGUSR1', false
|
129
|
+
reset(false)
|
124
130
|
@id = spawn
|
125
131
|
end
|
126
132
|
|
127
133
|
private
|
128
|
-
def _shutdown(sig)
|
134
|
+
def _shutdown(sig, close_channels=true)
|
129
135
|
Process.kill sig, @id
|
130
136
|
Process.wait @id
|
131
137
|
rescue Errno::ECHILD, Errno::ESRCH
|
132
138
|
ensure
|
133
139
|
@states = {dead: true} unless failed?
|
134
140
|
@shutdown = true
|
135
|
-
|
136
|
-
|
141
|
+
if close_channels
|
142
|
+
@channel.close
|
143
|
+
@s_channel.close
|
144
|
+
end
|
137
145
|
end
|
138
146
|
|
139
147
|
def synchronize!
|
@@ -144,16 +152,17 @@ private
|
|
144
152
|
@states
|
145
153
|
end
|
146
154
|
|
147
|
-
def reset
|
148
|
-
|
149
|
-
|
155
|
+
def reset(new_channels = true)
|
156
|
+
if new_channels
|
157
|
+
@channel = IChannel.new Marshal
|
158
|
+
@s_channel = IChannel.new Marshal
|
159
|
+
end
|
150
160
|
@shutdown = false
|
151
161
|
@states = {}
|
152
162
|
@frequency = 0
|
153
163
|
end
|
154
164
|
|
155
165
|
def spawn
|
156
|
-
reset
|
157
166
|
fork do
|
158
167
|
trap :SIGUSR1 do
|
159
168
|
XPool.log "#{::Process.pid} got request to shutdown."
|
@@ -172,8 +181,8 @@ private
|
|
172
181
|
end
|
173
182
|
sleep 0.05
|
174
183
|
rescue Exception => e
|
175
|
-
XPool.log "#{::Process.pid} has failed."
|
176
184
|
@s_channel.put failed: true, dead: true, backtrace: e.backtrace
|
185
|
+
XPool.log "Process with ID '#{@id}' has failed."
|
177
186
|
raise e
|
178
187
|
ensure
|
179
188
|
if @shutdown_requested && !@channel.readable?
|
data/lib/xpool/version.rb
CHANGED
data/test/support/io_writer.rb
CHANGED
@@ -13,9 +13,21 @@ class IOWriter
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def wrote_to_disk?
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
if File.exist? @path
|
17
|
+
val = File.read(@path)
|
18
|
+
FileUtils.rm_rf @path
|
19
|
+
val == 'true'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class IOSetupWriter < IOWriter
|
25
|
+
def setup
|
26
|
+
File.open @path, 'w' do |f|
|
27
|
+
f.write 'true'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def run
|
20
32
|
end
|
21
33
|
end
|
data/test/support/raiser.rb
CHANGED
data/test/xpool_process_test.rb
CHANGED
@@ -8,6 +8,16 @@ class XPoolProcessTest < Test::Unit::TestCase
|
|
8
8
|
@process.shutdown!
|
9
9
|
end
|
10
10
|
|
11
|
+
def test_resume_process_on_failed_process_queue
|
12
|
+
@process.schedule Raiser.new(0.1)
|
13
|
+
io_writers = Array.new(5) { IOWriter.new }
|
14
|
+
io_writers.each { |writer| @process.schedule writer }
|
15
|
+
until @process.failed?; sleep 0.1; end
|
16
|
+
@process.restart
|
17
|
+
sleep 0.5
|
18
|
+
io_writers.each { |io_writer| assert io_writer.wrote_to_disk? }
|
19
|
+
end
|
20
|
+
|
11
21
|
def test_busy_method
|
12
22
|
@process.schedule Sleeper.new(0.5)
|
13
23
|
sleep 0.1
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xpool
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.1
|
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: 2013-
|
12
|
+
date: 2013-04-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ichannel
|
@@ -70,7 +70,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
70
70
|
version: '0'
|
71
71
|
segments:
|
72
72
|
- 0
|
73
|
-
hash: -
|
73
|
+
hash: -3457064609731373945
|
74
74
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
75
|
none: false
|
76
76
|
requirements:
|
@@ -79,7 +79,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
79
|
version: '0'
|
80
80
|
segments:
|
81
81
|
- 0
|
82
|
-
hash: -
|
82
|
+
hash: -3457064609731373945
|
83
83
|
requirements: []
|
84
84
|
rubyforge_project:
|
85
85
|
rubygems_version: 1.8.23
|