This repository has been archived by the owner on Apr 14, 2021. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This PR adds a general purpose Retry class that can be re-used where-ever retry code is needed! It also allows you to call `bundle install --retry 3` which will attempt to connect to ruby gems 3 times before failing, and emit a warning message each time
- Loading branch information
Showing
7 changed files
with
118 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
module Bundler | ||
# General purpose class for retrying code that may fail | ||
class Retry | ||
attr_accessor :name, :max_attempts, :current_attempt | ||
|
||
def initialize(name, max_attempts = 1) | ||
@name = name | ||
@max_attempts = max_attempts | ||
end | ||
|
||
def attempt(&block) | ||
@current_attempt = 0 | ||
@failed = false | ||
@error = nil | ||
while keep_trying? do | ||
run(&block) | ||
end | ||
@result | ||
end | ||
alias :attempts :attempt | ||
|
||
private | ||
def run(&block) | ||
@failed = false | ||
@current_attempt += 1 | ||
@result = block.call | ||
rescue => e | ||
fail(e) | ||
end | ||
|
||
def fail(e) | ||
@failed = true | ||
raise e if last_attempt? | ||
return true unless name | ||
Bundler.ui.warn "Retrying #{name} due to error (#{current_attempt.next}/#{max_attempts}): #{e.message}" | ||
end | ||
|
||
def keep_trying? | ||
return true if current_attempt.zero? | ||
return false if last_attempt? | ||
return true if @failed | ||
end | ||
|
||
def last_attempt? | ||
current_attempt >= max_attempts | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
require 'spec_helper' | ||
|
||
describe "bundle retry" do | ||
it "return successful result if no errors" do | ||
attempts = 0 | ||
result = Bundler::Retry.new(nil, 3).attempt do | ||
attempts += 1 | ||
:success | ||
end | ||
expect(result).to eq(:success) | ||
expect(attempts).to eq(1) | ||
end | ||
|
||
it "returns the first valid result" do | ||
jobs = [->{ raise "foo" }, ->{ :bar }, ->{ raise "foo" }] | ||
attempts = 0 | ||
result = Bundler::Retry.new(nil, 3).attempt do | ||
attempts += 1 | ||
job = jobs.shift | ||
job.call | ||
end | ||
expect(result).to eq(:bar) | ||
expect(attempts).to eq(2) | ||
end | ||
|
||
it "raises the last error" do | ||
attempts = 0 | ||
expect { | ||
Bundler::Retry.new(nil, 3).attempt do | ||
attempts += 1 | ||
raise Bundler::GemfileNotFound | ||
end | ||
}.to raise_error(Bundler::GemfileNotFound) | ||
expect(attempts).to eq(3) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dc7dd9a
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is actually the wrong place to retry. We should be retrying around the network requests themselves, rather than trying to resolve multiple times. This actually causes the resolver to do a complete run three times if there's an error in the resolve:
Unfortunately that means I'm going to revert this before releasing 1.4 unless we can get something less intrusive before then.
/cc @schneems
dc7dd9a
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dc7dd9a
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.