Skip to content

Commit ba8947d

Browse files
john7doeCopilot
andcommitted
Cache the GHES instance check across organizations
enterprise? queried the meta endpoint on every call, and pending_members calls it once per organization. Whether an instance is GHES cannot vary between orgs on that instance, so this was one request per org for a constant answer. Caches against the address rather than the org signature. Checks for the key rather than using ||= because false is a valid cached answer, and is the answer github.com gives. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d95a67cd-ec62-497a-99fc-cf447ee1d49b
1 parent 7d46a91 commit ba8947d

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

lib/entitlements/service/github.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ def initialize(addr: nil, org:, token:, ou:, ignore_not_found: false)
5252
# need to be obtained only one time per organization, but might be used multiple times.
5353
Entitlements.cache[:github_pending_members] ||= {}
5454
Entitlements.cache[:github_org_members] ||= {}
55+
Entitlements.cache[:github_enterprise] ||= {}
5556
end
5657

5758
# Return the identifier, either the address specified or otherwise "github.com".
@@ -97,13 +98,23 @@ def org_members
9798
end
9899

99100
# Returns true if the github instance is an enterprise server instance
101+
#
102+
# Whether an instance is GHES is a property of the instance and not of any one organization,
103+
# so this is cached against the address rather than the org signature. Without this the meta
104+
# endpoint is queried once per organization, which is a request per org for an answer that
105+
# cannot vary between them. Note this caches false as well as true, so it checks for the key
106+
# rather than using ||=, since github.com correctly answers false here.
100107
Contract C::None => C::Bool
101108
def enterprise?
109+
instance_signature = addr || ""
110+
cache = Entitlements.cache[:github_enterprise]
111+
return cache[instance_signature] if cache.key?(instance_signature)
112+
102113
meta = Retryable.with_context(:default) do
103114
octokit.github_meta
104115
end
105116

106-
meta.key? :installed_version
117+
cache[instance_signature] = meta.key?(:installed_version)
107118
end
108119

109120
# Read the members of an organization who are in a "pending" role. These users should

spec/unit/entitlements/service/github_spec.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,28 @@
7070
})
7171
expect(subject.enterprise?).to eq(true)
7272
end
73+
74+
it "queries the API only once per instance across multiple organizations" do
75+
stub = stub_request(:get, "https://github.fake/api/v3/meta").
76+
to_return({
77+
body: JSON.dump({ verifiable_password_authentication: true }),
78+
headers: {
79+
content_type: "application/json; charset=utf-8"
80+
}
81+
})
82+
83+
other_org = described_class.new(
84+
addr: "https://github.fake/api/v3",
85+
org: "puppiesinc",
86+
token: "GoPackGo",
87+
ou: "ou=puppiesinc,ou=GitHub,dc=github,dc=fake",
88+
ignore_not_found: false
89+
)
90+
91+
expect(subject.enterprise?).to eq(false)
92+
expect(other_org.enterprise?).to eq(false)
93+
expect(stub).to have_been_requested.once
94+
end
7395
end
7496

7597
describe "#pending_members" do

0 commit comments

Comments
 (0)