using retriable gem

This commit is contained in:
Andrew Waage 2016-10-19 14:30:43 -07:00
parent 4f9cfdd337
commit 77ecafa978
3 changed files with 36 additions and 33 deletions

View File

@ -29,4 +29,6 @@ Gem::Specification.new do |spec|
spec.add_runtime_dependency("octokit", ["~> 4.0"]) spec.add_runtime_dependency("octokit", ["~> 4.0"])
spec.add_runtime_dependency("faraday-http-cache") spec.add_runtime_dependency("faraday-http-cache")
spec.add_runtime_dependency("activesupport") spec.add_runtime_dependency("activesupport")
spec.add_runtime_dependency("retriable", ["~> 2.1"])
end end

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'retriable'
module GitHubChangelogGenerator module GitHubChangelogGenerator
# A Fetcher responsible for all requests to GitHub and all basic manipulation with related data # A Fetcher responsible for all requests to GitHub and all basic manipulation with related data
# (such as filtering, validating, e.t.c) # (such as filtering, validating, e.t.c)
@ -281,47 +282,47 @@ Make sure, that you push tags to remote repo via 'git push --tags'"
# #
# @return [Object] returns exactly the same, what you put in the block, but wrap it with begin-rescue block # @return [Object] returns exactly the same, what you put in the block, but wrap it with begin-rescue block
def check_github_response def check_github_response
attempt = 1 Retriable.retriable(retry_options) do
begin yield
value = yield end
rescue Octokit::Unauthorized => e
Helper.log.error e.message
sys_abort("Error: wrong GitHub token")
rescue Octokit::Forbidden => e
attempt += 1
sleep_time = exp_backoff(attempt)
Helper.log.warn("sleeping #{sleep_time} second")
sys_sleep(sleep_time)
Helper.log.warn e.message rescue Octokit::Forbidden => e
Helper.log.error("#{e.class}: #{e.message}")
sys_abort("Exceeded retry limit")
rescue Octokit::Unauthorized => e
Helper.log.error("#{e.class}: #{e.message}")
sys_abort("Error: wrong GitHub token")
end
# Exponential backoff
def retry_options
{
:on => [Octokit::Forbidden],
:tries => MAX_FORBIDDEN_RETRIES,
:base_interval => sleep_base_interval,
:multiplier => 1.0,
:rand_factor => 0.0,
:on_retry => retry_callback
}
end
def sleep_base_interval
1.0
end
def retry_callback
Proc.new do |exception, try, elapsed_time, next_interval|
Helper.log.warn("RETRY - #{exception.class}: '#{exception.message}'")
Helper.log.warn("#{try} tries in #{elapsed_time} seconds and #{next_interval} seconds until the next try")
Helper.log.warn GH_RATE_LIMIT_EXCEEDED_MSG Helper.log.warn GH_RATE_LIMIT_EXCEEDED_MSG
Helper.log.warn @client.rate_limit Helper.log.warn @client.rate_limit
if attempt >= MAX_FORBIDDEN_RETRIES
sys_abort("Exceeded retry limit")
else
retry
end end
end end
value
end
def sys_sleep(seconds)
sleep(seconds)
end
def sys_abort(msg) def sys_abort(msg)
abort(msg) abort(msg)
end end
# Returns the exponential backoff (seconds) for this attempt number
#
# @param [Integer] attempt the attempt number
# @return [Integer] Exponential backoff seconds
def exp_backoff(attempt)
(2**attempt - 1) / 2
end
# Print specified line on the same string # Print specified line on the same string
# #
# @param [String] log_string # @param [String] log_string

View File

@ -29,9 +29,9 @@ describe GitHubChangelogGenerator::OctoFetcher do
context "when raises Octokit::Forbidden" do context "when raises Octokit::Forbidden" do
it "sleeps and retries and then aborts" do it "sleeps and retries and then aborts" do
retry_limit = GitHubChangelogGenerator::OctoFetcher::MAX_FORBIDDEN_RETRIES - 1 retry_limit = GitHubChangelogGenerator::OctoFetcher::MAX_FORBIDDEN_RETRIES - 1
allow(fetcher).to receive(:sleep_base_interval).and_return(0)
expect(fetcher).to receive(:sys_abort).with("Exceeded retry limit") expect(fetcher).to receive(:sys_abort).with("Exceeded retry limit")
expect(fetcher).to receive(:sys_sleep).exactly(retry_limit).times
fetcher.send(:check_github_response) { raise(Octokit::Forbidden) } fetcher.send(:check_github_response) { raise(Octokit::Forbidden) }
end end
end end