Commit 5d381260 authored by Bob Van Landuyt's avatar Bob Van Landuyt

Memoize feature available

parent ca43579b
...@@ -33,13 +33,19 @@ module EE ...@@ -33,13 +33,19 @@ module EE
# for a given Namespace plan. This method should consider ancestor groups # for a given Namespace plan. This method should consider ancestor groups
# being licensed. # being licensed.
def feature_available?(feature) def feature_available?(feature)
globally_available = License.feature_available?(feature) @feature_available ||= Hash.new do |h, feature|
h[feature] = load_feature_available(feature)
end
if current_application_settings.should_check_namespace_plan? @feature_available[feature]
globally_available && feature_available_in_plan?(feature)
else
globally_available
end end
def feature_available_in_plan?(feature)
@features_available_in_plan ||= Hash.new do |h, feature|
h[feature] = plans.any? { |plan| License.plan_includes_feature?(EE_PLANS[plan], feature) }
end
@features_available_in_plan[feature]
end end
def actual_shared_runners_minutes_limit def actual_shared_runners_minutes_limit
...@@ -59,6 +65,16 @@ module EE ...@@ -59,6 +65,16 @@ module EE
private private
def load_feature_available(feature)
globally_available = License.feature_available?(feature)
if current_application_settings.should_check_namespace_plan?
globally_available && feature_available_in_plan?(feature)
else
globally_available
end
end
def plans def plans
@ancestors_plans ||= @ancestors_plans ||=
if parent_id if parent_id
...@@ -67,13 +83,5 @@ module EE ...@@ -67,13 +83,5 @@ module EE
[plan] [plan]
end end
end end
def feature_available_in_plan?(feature)
@features_available_in_plan ||= Hash.new do |h, feature|
h[feature] = plans.any? { |plan| License.plan_includes_feature?(EE_PLANS[plan], feature) }
end
@features_available_in_plan[feature]
end
end end
end end
...@@ -344,11 +344,19 @@ module EE ...@@ -344,11 +344,19 @@ module EE
private private
def licensed_feature_available?(feature) def licensed_feature_available?(feature)
@licensed_feature_available ||= Hash.new do |h, feature|
h[feature] = load_licensed_feature_available(feature)
end
@licensed_feature_available[feature]
end
def load_licensed_feature_available(feature)
globally_available = License.feature_available?(feature) globally_available = License.feature_available?(feature)
if current_application_settings.should_check_namespace_plan? if current_application_settings.should_check_namespace_plan?
globally_available && globally_available &&
(public? && namespace.public? || namespace.feature_available?(feature)) (public? && namespace.public? || namespace.feature_available_in_plan?(feature))
else else
globally_available globally_available
end end
......
...@@ -59,6 +59,12 @@ describe Namespace, models: true do ...@@ -59,6 +59,12 @@ describe Namespace, models: true do
is_expected.to be_truthy is_expected.to be_truthy
end end
it 'only checks the plan once' do
expect(group).to receive(:load_feature_available).once.and_call_original
2.times { group.feature_available?(:service_desk) }
end
context 'when checking namespace plan' do context 'when checking namespace plan' do
before do before do
stub_application_setting_on_object(group, should_check_namespace_plan: true) stub_application_setting_on_object(group, should_check_namespace_plan: true)
......
...@@ -99,6 +99,13 @@ describe Project, models: true do ...@@ -99,6 +99,13 @@ describe Project, models: true do
end end
end end
it 'only loads licensed availability once' do
expect(project).to receive(:load_licensed_feature_available)
.once.and_call_original
2.times { project.feature_available?(:service_desk) }
end
context 'when feature symbol is not included on Namespace features code' do context 'when feature symbol is not included on Namespace features code' do
let(:feature) { :issues } let(:feature) { :issues }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment