Commit 0da8c72d authored by Stan Hu's avatar Stan Hu

Merge branch 'dblessing_group_projects_api_perf' into 'master'

Group API Plans Performance

See merge request gitlab-org/gitlab!77538
parents 474fcc18 3182a946
# frozen_string_literal: true
module Preloaders
class SingleHierarchyProjectGroupPlansPreloader
attr_reader :projects
def initialize(projects_relation)
@projects = projects_relation
end
def execute
# no-op in FOSS
end
end
end
Preloaders::SingleHierarchyProjectGroupPlansPreloader.prepend_mod_with('Preloaders::SingleHierarchyProjectGroupPlansPreloader')
---
name: group_project_api_preload_plans
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77538
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350176
milestone: '14.7'
type: development
group: group::authentication and authorization
default_enabled: false
# frozen_string_literal: true
module EE
module Preloaders
module SingleHierarchyProjectGroupPlansPreloader
def execute
return unless ::Feature.enabled?(:group_project_api_preload_plans, default_enabled: :yaml)
return unless ::Gitlab::CurrentSettings.should_check_namespace_plan?
return unless project = projects.take
plans = project.namespace.root_ancestor.plans
preload_plans(plans)
end
def preload_plans(plans)
return unless plans.any?
projects.each do |project|
project.namespace.memoized_plans = plans
end
end
end
end
end
......@@ -632,6 +632,54 @@ RSpec.describe API::Groups do
end
end
end
context 'when namespace license checks are enabled', :saas do
before do
enable_namespace_license_check!
end
context 'when there are plans and projects' do
let(:group) { create(:group_with_plan, plan: :ultimate_plan) }
before do
subgroup = create(:group, parent: group)
create(:project, group: group)
create(:project, group: subgroup)
end
it 'only loads plans once' do
expect(Plan).to receive(:hosted_plans_for_namespaces).once.and_call_original
get api("/groups/#{group.id}/projects", user), params: { include_subgroups: true }
expect(response).to have_gitlab_http_status(:ok)
end
context 'when the feature flag is disabled' do
before do
stub_feature_flags(group_project_api_preload_plans: false)
end
it 'does not preload plans' do
expect(Plan).to receive(:hosted_plans_for_namespaces).at_least(:twice).and_call_original
get api("/groups/#{group.id}/projects", user), params: { include_subgroups: true }
expect(response).to have_gitlab_http_status(:ok)
end
end
end
context 'when there are no projects' do
let(:group) { create(:group) }
it 'completes the request without error' do
get api("/groups/#{group.id}/projects", user), params: { include_subgroups: true }
expect(response).to have_gitlab_http_status(:ok)
end
end
end
end
describe 'GET group/:id/audit_events' do
......
......@@ -84,10 +84,11 @@ module API
paginate(projects)
end
def present_projects(params, projects)
def present_projects(params, projects, single_hierarchy: false)
options = {
with: params[:simple] ? Entities::BasicProjectDetails : Entities::Project,
current_user: current_user
current_user: current_user,
single_hierarchy: single_hierarchy
}
projects, options = with_custom_attributes(projects, options)
......@@ -306,7 +307,7 @@ module API
projects = find_group_projects(params, finder_options)
present_projects(params, projects)
present_projects(params, projects, single_hierarchy: true)
end
desc 'Get a list of shared projects in this group' do
......
......@@ -13,6 +13,7 @@ module API
preload_repository_cache(projects_relation)
Preloaders::UserMaxAccessLevelInProjectsPreloader.new(projects_relation, options[:current_user]).execute if options[:current_user]
Preloaders::SingleHierarchyProjectGroupPlansPreloader.new(projects_relation).execute if options[:single_hierarchy]
projects_relation
end
......
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