cmd/fetch: --retry with exponential backoff.

See discussion at Homebrew/homebrew-test-bot#826.
This commit is contained in:
Carlo Cabrera 2022-09-06 01:25:34 +08:00
parent 9cfa3d9f2a
commit 360052af57
No known key found for this signature in database
GPG Key ID: C74D447FC549A1D0

View File

@ -13,6 +13,8 @@ module Homebrew
module_function module_function
FETCH_MAX_TRIES = 5
sig { returns(CLI::Parser) } sig { returns(CLI::Parser) }
def fetch_args def fetch_args
Homebrew::CLI::Parser.new do Homebrew::CLI::Parser.new do
@ -31,7 +33,8 @@ module Homebrew
"seeing if an existing VCS cache has been updated." "seeing if an existing VCS cache has been updated."
switch "--retry", switch "--retry",
description: "Retry if downloading fails or re-download if the checksum of a previously cached " \ description: "Retry if downloading fails or re-download if the checksum of a previously cached " \
"version no longer matches." "version no longer matches. Tries at most #{FETCH_MAX_TRIES} times with " \
"exponential backoff."
switch "--deps", switch "--deps",
description: "Also download dependencies for any listed <formula>." description: "Also download dependencies for any listed <formula>."
switch "-s", "--build-from-source", switch "-s", "--build-from-source",
@ -159,10 +162,17 @@ module Homebrew
end end
def retry_fetch?(f, args:) def retry_fetch?(f, args:)
@fetch_failed ||= Set.new @fetch_failed ||= Hash.new { |h, k| h[k] = 1 }
if args.retry? && @fetch_failed.add?(f) if args.retry? && (@fetch_failed[f] < FETCH_MAX_TRIES)
ohai "Retrying download" wait = 2 ** @fetch_failed[f]
remaining = FETCH_MAX_TRIES - @fetch_failed[f]
what = "try".pluralize(remaining)
ohai "Retrying download in #{wait}s... (#{remaining} #{what} left)"
sleep wait
f.clear_cache f.clear_cache
@fetch_failed[f] += 1
true true
else else
Homebrew.failed = true Homebrew.failed = true