Commit 27b90b80 authored by Doug Stull's avatar Doug Stull Committed by Matthias Käppler

Fine tune a few queries found in GroupMembers#index

parent af8249ab
...@@ -4,6 +4,7 @@ class Groups::GroupMembersController < Groups::ApplicationController ...@@ -4,6 +4,7 @@ class Groups::GroupMembersController < Groups::ApplicationController
include MembershipActions include MembershipActions
include MembersPresentation include MembersPresentation
include SortingHelper include SortingHelper
include Gitlab::Utils::StrongMemoize
MEMBER_PER_PAGE_LIMIT = 50 MEMBER_PER_PAGE_LIMIT = 50
...@@ -21,6 +22,8 @@ class Groups::GroupMembersController < Groups::ApplicationController ...@@ -21,6 +22,8 @@ class Groups::GroupMembersController < Groups::ApplicationController
feature_category :authentication_and_authorization feature_category :authentication_and_authorization
helper_method :can_manage_members?
def index def index
preload_max_access preload_max_access
@sort = params[:sort].presence || sort_value_name @sort = params[:sort].presence || sort_value_name
...@@ -29,7 +32,7 @@ class Groups::GroupMembersController < Groups::ApplicationController ...@@ -29,7 +32,7 @@ class Groups::GroupMembersController < Groups::ApplicationController
.new(@group, current_user, params: filter_params) .new(@group, current_user, params: filter_params)
.execute(include_relations: requested_relations) .execute(include_relations: requested_relations)
if can_manage_members if can_manage_members?
@skip_groups = @group.related_group_ids @skip_groups = @group.related_group_ids
@invited_members = @members.invite @invited_members = @members.invite
...@@ -59,9 +62,11 @@ class Groups::GroupMembersController < Groups::ApplicationController ...@@ -59,9 +62,11 @@ class Groups::GroupMembersController < Groups::ApplicationController
current_user.max_access_for_group[@group.id] = @group.max_member_access(current_user) current_user.max_access_for_group[@group.id] = @group.max_member_access(current_user)
end end
def can_manage_members def can_manage_members?
strong_memoize(:can_manage_members) do
can?(current_user, :admin_group_member, @group) can?(current_user, :admin_group_member, @group)
end end
end
def present_invited_members(invited_members) def present_invited_members(invited_members)
present_members(invited_members present_members(invited_members
......
- add_page_specific_style 'page_bundles/members' - add_page_specific_style 'page_bundles/members'
- page_title _('Group members') - page_title _('Group members')
- can_manage_members = can?(current_user, :admin_group_member, @group) - show_invited_members = can_manage_members? && @invited_members.load.any?
- show_invited_members = can_manage_members && @invited_members.exists? - show_access_requests = can_manage_members? && @requesters.load.any?
- show_access_requests = can_manage_members && @requesters.exists?
- invited_active = params[:search_invited].present? || params[:invited_members_page].present? - invited_active = params[:search_invited].present? || params[:invited_members_page].present?
.js-remove-member-modal .js-remove-member-modal
.row.gl-mt-3 .row.gl-mt-3
.col-lg-12 .col-lg-12
.gl-display-flex.gl-flex-wrap .gl-display-flex.gl-flex-wrap
- if can_manage_members - if can_manage_members?
.gl-w-half.gl-xs-w-full .gl-w-half.gl-xs-w-full
%h4 %h4
= _('Group members') = _('Group members')
...@@ -21,7 +20,7 @@ ...@@ -21,7 +20,7 @@
.js-invite-group-trigger{ data: { classes: 'gl-mt-3 gl-sm-w-auto gl-w-full', display_text: _('Invite a group') } } .js-invite-group-trigger{ data: { classes: 'gl-mt-3 gl-sm-w-auto gl-w-full', display_text: _('Invite a group') } }
.js-invite-members-trigger{ data: { variant: 'success', classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3', display_text: _('Invite members') } } .js-invite-members-trigger{ data: { variant: 'success', classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3', display_text: _('Invite members') } }
= render 'groups/invite_members_modal', group: @group = render 'groups/invite_members_modal', group: @group
- if can_manage_members && Feature.disabled?(:invite_members_group_modal, @group) - if can_manage_members? && Feature.disabled?(:invite_members_group_modal, @group)
%hr.gl-mt-4 %hr.gl-mt-4
%ul.nav-links.nav.nav-tabs.gitlab-tabs{ role: 'tablist' } %ul.nav-links.nav.nav-tabs.gitlab-tabs{ role: 'tablist' }
%li.nav-tab{ role: 'presentation' } %li.nav-tab{ role: 'presentation' }
...@@ -42,7 +41,7 @@ ...@@ -42,7 +41,7 @@
%span %span
= _('Members') = _('Members')
%span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @members.total_count %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= @members.total_count
- if @group.shared_with_group_links.any? - if @group.shared_with_group_links.present?
%li.nav-item %li.nav-item
= link_to '#tab-groups', class: ['nav-link'] , data: { toggle: 'tab', qa_selector: 'groups_list_tab' } do = link_to '#tab-groups', class: ['nav-link'] , data: { toggle: 'tab', qa_selector: 'groups_list_tab' } do
%span %span
...@@ -65,7 +64,7 @@ ...@@ -65,7 +64,7 @@
.js-group-members-list{ data: group_members_list_data_attributes(@group, @members, { param_name: :page, params: { invited_members_page: nil, search_invited: nil } }) } .js-group-members-list{ data: group_members_list_data_attributes(@group, @members, { param_name: :page, params: { invited_members_page: nil, search_invited: nil } }) }
.loading .loading
.gl-spinner.gl-spinner-md .gl-spinner.gl-spinner-md
- if @group.shared_with_group_links.any? - if @group.shared_with_group_links.present?
#tab-groups.tab-pane #tab-groups.tab-pane
.js-group-group-links-list{ data: group_group_links_list_data_attributes(@group) } .js-group-group-links-list{ data: group_group_links_list_data_attributes(@group) }
.loading .loading
......
---
title: Fine tune a few queries found in GroupMembers#index
merge_request: 60857
author:
type: performance
...@@ -27,20 +27,21 @@ RSpec.describe Groups::GroupMembersController do ...@@ -27,20 +27,21 @@ RSpec.describe Groups::GroupMembersController do
create_list(:group_member, 5, group: group, created_by: user) create_list(:group_member, 5, group: group, created_by: user)
create_list(:group_member, 5, :invited, :developer, group: group, created_by: user) create_list(:group_member, 5, :invited, :developer, group: group, created_by: user)
create_list(:group_member, 5, :access_request, group: group) create_list(:group_member, 5, :access_request, group: group)
# locally 87 vs 128 # locally 47 vs 52 GDK vs 57 CI
unresolved_n_plus_ones = 8 # 1 in GDK, 5 in CI hard to say - multiple should likely be lower now unresolved_n_plus_ones = 5 # still have a few queries created by can_update/can_remove that should be reduced
# using_license 84 vs 115 = ~13 multiple_members_threshold = 5 # GDK vs CI difference
# can_update 82 vs 102 = ~13
# can_remove 80 vs 89 = ~13
# can_resend 80 + 5 = ~4
# solving access level reduced from ~80 to ~50
# still have a few queries created by can_update/can_remove that should be reduced
multiple_members_threshold = 5
expect do expect do
get :index, params: { group_id: group.reload } get :index, params: { group_id: group.reload }
end.not_to exceed_all_query_limit(control.count).with_threshold(multiple_members_threshold + unresolved_n_plus_ones) end.not_to exceed_all_query_limit(control.count).with_threshold(multiple_members_threshold + unresolved_n_plus_ones)
end end
it 'avoids extra group_link database queries utilizing pre-loading' do
control = ActiveRecord::QueryRecorder.new { get :index, params: { group_id: group } }
count_queries = control.occurrences_by_line_method.first[1][:occurrences].any? { |i| i.include?('SELECT 1 AS one FROM "group_group_links" WHERE "group_group_links"') }
expect(count_queries).to be(false)
end
end end
end end
......
...@@ -24,7 +24,7 @@ RSpec.describe Groups::GroupMembersController do ...@@ -24,7 +24,7 @@ RSpec.describe Groups::GroupMembersController do
expect(response).to render_template(:index) expect(response).to render_template(:index)
end end
context 'user with owner access' do context 'when user can manage members' do
let_it_be(:invited) { create_list(:group_member, 3, :invited, group: group) } let_it_be(:invited) { create_list(:group_member, 3, :invited, group: group) }
before do before do
...@@ -71,6 +71,19 @@ RSpec.describe Groups::GroupMembersController do ...@@ -71,6 +71,19 @@ RSpec.describe Groups::GroupMembersController do
end end
end end
context 'when user cannot manage members' do
before do
sign_in(user)
end
it 'does not assign invited members or skip_groups', :aggregate_failures do
get :index, params: { group_id: group }
expect(assigns(:invited_members)).to be_nil
expect(assigns(:skip_groups)).to be_nil
end
end
context 'when user has owner access to subgroup' do context 'when user has owner access to subgroup' do
let_it_be(:nested_group) { create(:group, parent: group) } let_it_be(:nested_group) { create(:group, parent: group) }
let_it_be(:nested_group_user) { create(:user) } let_it_be(:nested_group_user) { create(:user) }
......
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