Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit8aea604

Browse files
authored
fix: use unique workspace owners over unique users (#11044)
1 parent091fdd6 commit8aea604

File tree

10 files changed

+212
-2
lines changed

10 files changed

+212
-2
lines changed

‎coderd/database/dbauthz/dbauthz.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,6 +2053,13 @@ func (q *querier) GetWorkspaceResourcesCreatedAfter(ctx context.Context, created
20532053
returnq.db.GetWorkspaceResourcesCreatedAfter(ctx,createdAt)
20542054
}
20552055

2056+
func (q*querier)GetWorkspaceUniqueOwnerCountByTemplateIDs(ctx context.Context,templateIds []uuid.UUID) ([]database.GetWorkspaceUniqueOwnerCountByTemplateIDsRow,error) {
2057+
iferr:=q.authorizeContext(ctx,rbac.ActionRead,rbac.ResourceSystem);err!=nil {
2058+
returnnil,err
2059+
}
2060+
returnq.db.GetWorkspaceUniqueOwnerCountByTemplateIDs(ctx,templateIds)
2061+
}
2062+
20562063
func (q*querier)GetWorkspaces(ctx context.Context,arg database.GetWorkspacesParams) ([]database.GetWorkspacesRow,error) {
20572064
prep,err:=prepareSQLFilter(ctx,q.auth,rbac.ActionRead,rbac.ResourceWorkspace.Type)
20582065
iferr!=nil {

‎coderd/database/dbmem/dbmem.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4520,6 +4520,36 @@ func (q *FakeQuerier) GetWorkspaceResourcesCreatedAfter(_ context.Context, after
45204520
returnresources,nil
45214521
}
45224522

4523+
func (q*FakeQuerier)GetWorkspaceUniqueOwnerCountByTemplateIDs(_ context.Context,templateIds []uuid.UUID) ([]database.GetWorkspaceUniqueOwnerCountByTemplateIDsRow,error) {
4524+
q.mutex.RLock()
4525+
deferq.mutex.RUnlock()
4526+
4527+
workspaceOwners:=make(map[uuid.UUID]map[uuid.UUID]struct{})
4528+
for_,workspace:=rangeq.workspaces {
4529+
ifworkspace.Deleted {
4530+
continue
4531+
}
4532+
if!slices.Contains(templateIds,workspace.TemplateID) {
4533+
continue
4534+
}
4535+
_,ok:=workspaceOwners[workspace.TemplateID]
4536+
if!ok {
4537+
workspaceOwners[workspace.TemplateID]=make(map[uuid.UUID]struct{})
4538+
}
4539+
workspaceOwners[workspace.TemplateID][workspace.OwnerID]=struct{}{}
4540+
}
4541+
resp:=make([]database.GetWorkspaceUniqueOwnerCountByTemplateIDsRow,0)
4542+
for_,templateID:=rangetemplateIds {
4543+
count:=len(workspaceOwners[templateID])
4544+
resp=append(resp, database.GetWorkspaceUniqueOwnerCountByTemplateIDsRow{
4545+
TemplateID:templateID,
4546+
UniqueOwnersSum:int64(count),
4547+
})
4548+
}
4549+
4550+
returnresp,nil
4551+
}
4552+
45234553
func (q*FakeQuerier)GetWorkspaces(ctx context.Context,arg database.GetWorkspacesParams) ([]database.GetWorkspacesRow,error) {
45244554
iferr:=validateDatabaseType(arg);err!=nil {
45254555
returnnil,err

‎coderd/database/dbmetrics/dbmetrics.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/dbmock/dbmock.go

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/querier.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/queries.sql.go

Lines changed: 38 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/queries/workspaces.sql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,15 @@ WHERE
287287
ANDLOWER("name")=LOWER(@name)
288288
ORDER BY created_atDESC;
289289

290+
-- name: GetWorkspaceUniqueOwnerCountByTemplateIDs :many
291+
SELECT
292+
template_id,COUNT(DISTINCT owner_id)AS unique_owners_sum
293+
FROM
294+
workspaces
295+
WHERE
296+
template_id= ANY(@template_ids :: uuid[])AND deleted= false
297+
GROUP BY template_id;
298+
290299
-- name: InsertWorkspace :one
291300
INSERT INTO
292301
workspaces (

‎coderd/metricscache/metricscache.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ type Cache struct {
5252
deploymentDAUResponses atomic.Pointer[map[int]codersdk.DAUsResponse]
5353
templateDAUResponses atomic.Pointer[map[int]map[uuid.UUID]codersdk.DAUsResponse]
5454
templateUniqueUsers atomic.Pointer[map[uuid.UUID]int]
55+
templateWorkspaceOwners atomic.Pointer[map[uuid.UUID]int]
5556
templateAverageBuildTime atomic.Pointer[map[uuid.UUID]database.GetTemplateAverageBuildTimeRow]
5657
deploymentStatsResponse atomic.Pointer[codersdk.DeploymentStats]
5758

@@ -206,6 +207,7 @@ func (c *Cache) refreshTemplateDAUs(ctx context.Context) error {
206207
var (
207208
templateDAUs=make(map[int]map[uuid.UUID]codersdk.DAUsResponse,len(templates))
208209
templateUniqueUsers=make(map[uuid.UUID]int)
210+
templateWorkspaceOwners=make(map[uuid.UUID]int)
209211
templateAverageBuildTimes=make(map[uuid.UUID]database.GetTemplateAverageBuildTimeRow)
210212
)
211213

@@ -214,7 +216,9 @@ func (c *Cache) refreshTemplateDAUs(ctx context.Context) error {
214216
returnxerrors.Errorf("deployment daus: %w",err)
215217
}
216218

219+
ids:=make([]uuid.UUID,0,len(templates))
217220
for_,template:=rangetemplates {
221+
ids=append(ids,template.ID)
218222
for_,tzOffset:=rangetemplateTimezoneOffsets {
219223
rows,err:=c.database.GetTemplateDAUs(ctx, database.GetTemplateDAUsParams{
220224
TemplateID:template.ID,
@@ -249,6 +253,17 @@ func (c *Cache) refreshTemplateDAUs(ctx context.Context) error {
249253
}
250254
templateAverageBuildTimes[template.ID]=templateAvgBuildTime
251255
}
256+
257+
owners,err:=c.database.GetWorkspaceUniqueOwnerCountByTemplateIDs(ctx,ids)
258+
iferr!=nil {
259+
returnxerrors.Errorf("get workspace unique owner count by template ids: %w",err)
260+
}
261+
262+
for_,owner:=rangeowners {
263+
templateWorkspaceOwners[owner.TemplateID]=int(owner.UniqueOwnersSum)
264+
}
265+
266+
c.templateWorkspaceOwners.Store(&templateWorkspaceOwners)
252267
c.templateDAUResponses.Store(&templateDAUs)
253268
c.templateUniqueUsers.Store(&templateUniqueUsers)
254269
c.templateAverageBuildTime.Store(&templateAverageBuildTimes)
@@ -469,6 +484,21 @@ func (c *Cache) TemplateBuildTimeStats(id uuid.UUID) codersdk.TemplateBuildTimeS
469484
}
470485
}
471486

487+
func (c*Cache)TemplateWorkspaceOwners(id uuid.UUID) (int,bool) {
488+
m:=c.templateWorkspaceOwners.Load()
489+
ifm==nil {
490+
// Data loading.
491+
return-1,false
492+
}
493+
494+
resp,ok:= (*m)[id]
495+
if!ok {
496+
// Probably no data.
497+
return-1,false
498+
}
499+
returnresp,true
500+
}
501+
472502
func (c*Cache)DeploymentStats() (codersdk.DeploymentStats,bool) {
473503
deploymentStats:=c.deploymentStatsResponse.Load()
474504
ifdeploymentStats==nil {

‎coderd/metricscache/metricscache_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,74 @@ func TestCache_TemplateUsers(t *testing.T) {
254254
}
255255
}
256256

257+
funcTestCache_TemplateWorkspaceOwners(t*testing.T) {
258+
t.Parallel()
259+
var ()
260+
261+
var (
262+
db=dbmem.New()
263+
cache=metricscache.New(db,slogtest.Make(t,nil), metricscache.Intervals{
264+
TemplateDAUs:testutil.IntervalFast,
265+
})
266+
)
267+
268+
defercache.Close()
269+
270+
user1:=dbgen.User(t,db, database.User{})
271+
user2:=dbgen.User(t,db, database.User{})
272+
template:=dbgen.Template(t,db, database.Template{
273+
Provisioner:database.ProvisionerTypeEcho,
274+
})
275+
require.Eventuallyf(t,func()bool {
276+
count,ok:=cache.TemplateWorkspaceOwners(template.ID)
277+
returnok&&count==0
278+
},testutil.WaitShort,testutil.IntervalMedium,
279+
"TemplateWorkspaceOwners never populated 0 owners",
280+
)
281+
282+
dbgen.Workspace(t,db, database.Workspace{
283+
TemplateID:template.ID,
284+
OwnerID:user1.ID,
285+
})
286+
287+
require.Eventuallyf(t,func()bool {
288+
count,_:=cache.TemplateWorkspaceOwners(template.ID)
289+
returncount==1
290+
},testutil.WaitShort,testutil.IntervalMedium,
291+
"TemplateWorkspaceOwners never populated 1 owner",
292+
)
293+
294+
workspace2:=dbgen.Workspace(t,db, database.Workspace{
295+
TemplateID:template.ID,
296+
OwnerID:user2.ID,
297+
})
298+
299+
require.Eventuallyf(t,func()bool {
300+
count,_:=cache.TemplateWorkspaceOwners(template.ID)
301+
returncount==2
302+
},testutil.WaitShort,testutil.IntervalMedium,
303+
"TemplateWorkspaceOwners never populated 2 owners",
304+
)
305+
306+
// 3rd workspace should not be counted since we have the same owner as workspace2.
307+
dbgen.Workspace(t,db, database.Workspace{
308+
TemplateID:template.ID,
309+
OwnerID:user1.ID,
310+
})
311+
312+
db.UpdateWorkspaceDeletedByID(context.Background(), database.UpdateWorkspaceDeletedByIDParams{
313+
ID:workspace2.ID,
314+
Deleted:true,
315+
})
316+
317+
require.Eventuallyf(t,func()bool {
318+
count,_:=cache.TemplateWorkspaceOwners(template.ID)
319+
returncount==1
320+
},testutil.WaitShort,testutil.IntervalMedium,
321+
"TemplateWorkspaceOwners never populated 1 owner after delete",
322+
)
323+
}
324+
257325
funcclockTime(t time.Time,hour,minute,secint) time.Time {
258326
returntime.Date(t.Year(),t.Month(),t.Day(),hour,minute,sec,t.Nanosecond(),t.Location())
259327
}

‎coderd/templates.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,12 @@ func (api *API) convertTemplate(
831831
template database.Template,
832832
) codersdk.Template {
833833
templateAccessControl:= (*(api.Options.AccessControlStore.Load())).GetTemplateAccessControl(template)
834-
activeCount,_:=api.metricsCache.TemplateUniqueUsers(template.ID)
834+
835+
owners:=0
836+
o,ok:=api.metricsCache.TemplateWorkspaceOwners(template.ID)
837+
ifok {
838+
owners=o
839+
}
835840

836841
buildTimeStats:=api.metricsCache.TemplateBuildTimeStats(template.ID)
837842

@@ -849,7 +854,7 @@ func (api *API) convertTemplate(
849854
DisplayName:template.DisplayName,
850855
Provisioner:codersdk.ProvisionerType(template.Provisioner),
851856
ActiveVersionID:template.ActiveVersionID,
852-
ActiveUserCount:activeCount,
857+
ActiveUserCount:owners,
853858
BuildTimeStats:buildTimeStats,
854859
Description:template.Description,
855860
Icon:template.Icon,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp