mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix: drop N+1 db query on template ACL available (#25465)
Fixes [PLAT-149](https://linear.app/codercom/issue/PLAT-149/template-permissions-search-is-extremely-slow-with-many-groups). `/acl/available` ran a db query per group. A deployment with >5,000 groups made this route extremely slow.
This commit is contained in:
@@ -3476,6 +3476,15 @@ func (q *querier) GetGroupMembersCountByGroupID(ctx context.Context, arg databas
|
||||
return memberCount, nil
|
||||
}
|
||||
|
||||
func (q *querier) GetGroupMembersCountByGroupIDs(ctx context.Context, arg database.GetGroupMembersCountByGroupIDsParams) ([]database.GetGroupMembersCountByGroupIDsRow, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceGroup); err != nil {
|
||||
// Ideally we would check read access on each group ID, but that would be N queries.
|
||||
// So this function is really only usable by admins.
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetGroupMembersCountByGroupIDs(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) GetGroups(ctx context.Context, arg database.GetGroupsParams) ([]database.GetGroupsRow, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceSystem); err == nil {
|
||||
// Optimize this query for system users as it is used in telemetry.
|
||||
|
||||
@@ -1820,6 +1820,18 @@ func (s *MethodTestSuite) TestGroup() {
|
||||
check.Args(arg).Asserts(g, policy.ActionRead)
|
||||
}))
|
||||
|
||||
s.Run("GetGroupMembersCountByGroupIDs", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
|
||||
g1 := testutil.Fake(s.T(), faker, database.Group{})
|
||||
g2 := testutil.Fake(s.T(), faker, database.Group{})
|
||||
arg := database.GetGroupMembersCountByGroupIDsParams{GroupIds: []uuid.UUID{g1.ID, g2.ID}, IncludeSystem: false}
|
||||
rows := []database.GetGroupMembersCountByGroupIDsRow{
|
||||
{GroupID: g1.ID, MemberCount: 1},
|
||||
{GroupID: g2.ID, MemberCount: 2},
|
||||
}
|
||||
dbm.EXPECT().GetGroupMembersCountByGroupIDs(gomock.Any(), arg).Return(rows, nil).AnyTimes()
|
||||
check.Args(arg).Asserts(rbac.ResourceGroup, policy.ActionRead).Returns(rows)
|
||||
}))
|
||||
|
||||
s.Run("GetGroupMembers", s.Mocked(func(dbm *dbmock.MockStore, _ *gofakeit.Faker, check *expects) {
|
||||
dbm.EXPECT().GetGroupMembers(gomock.Any(), false).Return([]database.GroupMember{}, nil).AnyTimes()
|
||||
check.Args(false).Asserts(rbac.ResourceSystem, policy.ActionRead)
|
||||
|
||||
Reference in New Issue
Block a user