forked from dependabot/dependabot-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathregistry_client.rb
78 lines (68 loc) · 2.21 KB
/
registry_client.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# typed: strong
# frozen_string_literal: true
require "sorbet-runtime"
require "dependabot/shared_helpers"
# This class provides a thin wrapper around our normal usage of Excon as a simple HTTP client in order to
# provide some minor caching functionality.
#
# This is not used to support full response caching currently, we just use it to ensure we detect unreachable
# hosts and fast-fail on any subsequent requests to them to avoid excessive use of retries and connect- or
# read-timeouts as some jobs tend to be sensitive to exceeding our overall 45 minute timeout.
module Dependabot
class RegistryClient
extend T::Sig
@cached_errors = T.let({}, T::Hash[T.nilable(String), Excon::Error::Timeout])
sig do
params(
url: String,
headers: T::Hash[Symbol, T.untyped],
options: T::Hash[Symbol, T.untyped]
)
.returns(Excon::Response)
end
def self.get(url:, headers: {}, options: {})
raise T.must(cached_error_for(url)) if cached_error_for(url)
Excon.get(
url,
idempotent: true,
**SharedHelpers.excon_defaults({ headers: headers }.merge(options))
)
rescue Excon::Error::Timeout => e
cache_error(url, e)
raise e
end
sig do
params(
url: String,
headers: T::Hash[Symbol, T.untyped],
options: T::Hash[Symbol, T.untyped]
)
.returns(Excon::Response)
end
def self.head(url:, headers: {}, options: {})
raise T.must(cached_error_for(url)) if cached_error_for(url)
Excon.head(
url,
idempotent: true,
**SharedHelpers.excon_defaults({ headers: headers }.merge(options))
)
rescue Excon::Error::Timeout => e
cache_error(url, e)
raise e
end
sig { void }
def self.clear_cache!
@cached_errors = {}
end
sig { params(url: String, error: Excon::Error::Timeout).void }
private_class_method def self.cache_error(url, error)
host = URI(url).host
@cached_errors[host] = error
end
sig { params(url: String).returns(T.nilable(Excon::Error::Timeout)) }
private_class_method def self.cached_error_for(url)
host = URI(url).host
@cached_errors.fetch(host, nil)
end
end
end