mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Timeout parallel test worker processes
This commit is contained in:
parent
1831693c1f
commit
478187e9a3
Notes:
git
2021-10-17 16:34:20 +09:00
1 changed files with 27 additions and 5 deletions
|
@ -281,6 +281,7 @@ module Test
|
||||||
options[:parallel] ||= 1
|
options[:parallel] ||= 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@worker_timeout = EnvUtil.apply_timeout_scale(options[:worker_timeout] || 180)
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -303,6 +304,10 @@ module Test
|
||||||
options[:parallel] = a.to_i
|
options[:parallel] = a.to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
|
opts.on '--worker-timeout=N', Integer, "Timeout workers not responding in N seconds" do |a|
|
||||||
|
options[:worker_timeout] = a
|
||||||
|
end
|
||||||
|
|
||||||
opts.on '--separate', "Restart job process after one testcase has done" do
|
opts.on '--separate', "Restart job process after one testcase has done" do
|
||||||
options[:parallel] ||= 1
|
options[:parallel] ||= 1
|
||||||
options[:separate] = true
|
options[:separate] = true
|
||||||
|
@ -337,6 +342,7 @@ module Test
|
||||||
|
|
||||||
attr_reader :quit_called
|
attr_reader :quit_called
|
||||||
attr_accessor :start_time
|
attr_accessor :start_time
|
||||||
|
attr_accessor :response_at
|
||||||
|
|
||||||
@@worker_number = 0
|
@@worker_number = 0
|
||||||
|
|
||||||
|
@ -350,6 +356,7 @@ module Test
|
||||||
@loadpath = []
|
@loadpath = []
|
||||||
@hooks = {}
|
@hooks = {}
|
||||||
@quit_called = false
|
@quit_called = false
|
||||||
|
@response_at = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def name
|
def name
|
||||||
|
@ -369,6 +376,7 @@ module Test
|
||||||
puts "run #{task} #{type}"
|
puts "run #{task} #{type}"
|
||||||
@status = :prepare
|
@status = :prepare
|
||||||
@start_time = Time.now
|
@start_time = Time.now
|
||||||
|
@response_at = @start_time
|
||||||
rescue Errno::EPIPE
|
rescue Errno::EPIPE
|
||||||
died
|
died
|
||||||
rescue IOError
|
rescue IOError
|
||||||
|
@ -385,6 +393,7 @@ module Test
|
||||||
|
|
||||||
def read
|
def read
|
||||||
res = (@status == :quit) ? @io.read : @io.gets
|
res = (@status == :quit) ? @io.read : @io.gets
|
||||||
|
@response_at = Time.now
|
||||||
res && res.chomp
|
res && res.chomp
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -515,9 +524,11 @@ module Test
|
||||||
@ios.delete worker.io
|
@ios.delete worker.io
|
||||||
end
|
end
|
||||||
|
|
||||||
def quit_workers
|
def quit_workers(&cond)
|
||||||
return if @workers.empty?
|
return if @workers.empty?
|
||||||
|
closed = []
|
||||||
@workers.reject! do |worker|
|
@workers.reject! do |worker|
|
||||||
|
next unless cond&.call(worker)
|
||||||
begin
|
begin
|
||||||
Timeout.timeout(1) do
|
Timeout.timeout(1) do
|
||||||
worker.quit
|
worker.quit
|
||||||
|
@ -525,9 +536,11 @@ module Test
|
||||||
rescue Errno::EPIPE
|
rescue Errno::EPIPE
|
||||||
rescue Timeout::Error
|
rescue Timeout::Error
|
||||||
end
|
end
|
||||||
|
closed << worker
|
||||||
worker.close
|
worker.close
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return closed if cond
|
||||||
return if @workers.empty?
|
return if @workers.empty?
|
||||||
begin
|
begin
|
||||||
Timeout.timeout(0.2 * @workers.size) do
|
Timeout.timeout(0.2 * @workers.size) do
|
||||||
|
@ -646,14 +659,23 @@ module Test
|
||||||
begin
|
begin
|
||||||
[@tasks.size, @options[:parallel]].min.times {launch_worker}
|
[@tasks.size, @options[:parallel]].min.times {launch_worker}
|
||||||
|
|
||||||
while _io = IO.select(@ios)[0]
|
while true
|
||||||
break if _io.any? do |io|
|
timeout = [(@workers.filter_map {|w| w.response_at}.min&.-(Time.now) || 0) + @worker_timeout, 1].max
|
||||||
|
|
||||||
|
if !(_io = IO.select(@ios, nil, nil, timeout))
|
||||||
|
timeout = Time.now - @worker_timeout
|
||||||
|
@tasks.unshift(*quit_workers {|w| w.response_at < timeout}&.map(&:real_file))
|
||||||
|
elsif _io.first.any? {|io|
|
||||||
@need_quit or
|
@need_quit or
|
||||||
(deal(io, type, result, rep).nil? and
|
(deal(io, type, result, rep).nil? and
|
||||||
!@workers.any? {|x| [:running, :prepare].include? x.status})
|
!@workers.any? {|x| [:running, :prepare].include? x.status})
|
||||||
|
}
|
||||||
|
break
|
||||||
end
|
end
|
||||||
if @jobserver and @job_tokens and !@tasks.empty? and !@workers.any? {|x| x.status == :ready}
|
if @jobserver and @job_tokens and !@tasks.empty? and
|
||||||
t = @jobserver[0].read_nonblock([@tasks.size, @options[:parallel]].min, exception: false)
|
((newjobs = [@tasks.size, @options[:parallel]].min) > @workers.size or
|
||||||
|
!@workers.any? {|x| x.status == :ready})
|
||||||
|
t = @jobserver[0].read_nonblock(newjobs, exception: false)
|
||||||
if String === t
|
if String === t
|
||||||
@job_tokens << t
|
@job_tokens << t
|
||||||
t.size.times {launch_worker}
|
t.size.times {launch_worker}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue