Skip to content

Commit af88313

Browse files
committed
downloader: add support for auto retry
1 parent 3800784 commit af88313

File tree

1 file changed

+46
-36
lines changed

1 file changed

+46
-36
lines changed

lib/datasets/downloader.rb

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -30,47 +30,57 @@ def download(output_path, &block)
3030

3131
output_path.parent.mkpath
3232

33-
headers = {
34-
"Accept-Encoding" => "identity",
35-
"User-Agent" => "Red Datasets/#{VERSION}",
36-
}
37-
start = nil
38-
partial_output_path = Pathname.new("#{output_path}.partial")
39-
if partial_output_path.exist?
40-
start = partial_output_path.size
41-
headers["Range"] = "bytes=#{start}-"
42-
end
43-
44-
start_http(@url, headers) do |response|
45-
if response.is_a?(Net::HTTPPartialContent)
46-
mode = "ab"
47-
else
48-
start = nil
49-
mode = "wb"
33+
n_retries = 0
34+
n_max_retries = 5
35+
begin
36+
headers = {
37+
"Accept-Encoding" => "identity",
38+
"User-Agent" => "Red Datasets/#{VERSION}",
39+
}
40+
start = nil
41+
partial_output_path = Pathname.new("#{output_path}.partial")
42+
if partial_output_path.exist?
43+
start = partial_output_path.size
44+
headers["Range"] = "bytes=#{start}-"
5045
end
5146

52-
base_name = @url.path.split("/").last
53-
size_current = 0
54-
size_max = response.content_length
55-
if start
56-
size_current += start
57-
size_max += start
58-
yield_chunks(partial_output_path, &block) if block_given?
59-
end
60-
progress_reporter = ProgressReporter.new(base_name, size_max)
61-
partial_output_path.open(mode) do |output|
62-
response.read_body do |chunk|
63-
size_current += chunk.bytesize
64-
progress_reporter.report(size_current)
65-
output.write(chunk)
66-
yield(chunk) if block_given?
47+
start_http(@url, headers) do |response|
48+
if response.is_a?(Net::HTTPPartialContent)
49+
mode = "ab"
50+
else
51+
start = nil
52+
mode = "wb"
53+
end
54+
55+
base_name = @url.path.split("/").last
56+
size_current = 0
57+
size_max = response.content_length
58+
if start
59+
size_current += start
60+
size_max += start
61+
if block_given? and n_retries.zero?
62+
yield_chunks(partial_output_path, &block)
63+
end
64+
end
65+
progress_reporter = ProgressReporter.new(base_name, size_max)
66+
partial_output_path.open(mode) do |output|
67+
response.read_body do |chunk|
68+
size_current += chunk.bytesize
69+
progress_reporter.report(size_current)
70+
output.write(chunk)
71+
yield(chunk) if block_given?
72+
end
6773
end
6874
end
75+
FileUtils.mv(partial_output_path, output_path)
76+
rescue Net::ReadTimeout => error
77+
n_retries += 1
78+
retry if n_retries < n_max_retries
79+
raise
80+
rescue TooManyRedirects => error
81+
last_url = error.message[/\Atoo many redirections: (.+)\z/, 1]
82+
raise TooManyRedirects, "too many redirections: #{@url} .. #{last_url}"
6983
end
70-
FileUtils.mv(partial_output_path, output_path)
71-
rescue TooManyRedirects => error
72-
last_url = error.message[/\Atoo many redirections: (.+)\z/, 1]
73-
raise TooManyRedirects, "too many redirections: #{@url} .. #{last_url}"
7484
end
7585

7686
private def start_http(url, headers, limit = 10, &block)

0 commit comments

Comments
 (0)