mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat(site): Add deployment-wide DAU chart (#5810)
This commit is contained in:
@@ -27,6 +27,7 @@ type Cache struct {
|
||||
database database.Store
|
||||
log slog.Logger
|
||||
|
||||
deploymentDAUResponses atomic.Pointer[codersdk.DeploymentDAUsResponse]
|
||||
templateDAUResponses atomic.Pointer[map[uuid.UUID]codersdk.TemplateDAUsResponse]
|
||||
templateUniqueUsers atomic.Pointer[map[uuid.UUID]int]
|
||||
templateAverageBuildTime atomic.Pointer[map[uuid.UUID]database.GetTemplateAverageBuildTimeRow]
|
||||
@@ -110,6 +111,28 @@ func convertDAUResponse(rows []database.GetTemplateDAUsRow) codersdk.TemplateDAU
|
||||
return resp
|
||||
}
|
||||
|
||||
func convertDeploymentDAUResponse(rows []database.GetDeploymentDAUsRow) codersdk.DeploymentDAUsResponse {
|
||||
respMap := make(map[time.Time][]uuid.UUID)
|
||||
for _, row := range rows {
|
||||
respMap[row.Date] = append(respMap[row.Date], row.UserID)
|
||||
}
|
||||
|
||||
dates := maps.Keys(respMap)
|
||||
slices.SortFunc(dates, func(a, b time.Time) bool {
|
||||
return a.Before(b)
|
||||
})
|
||||
|
||||
var resp codersdk.DeploymentDAUsResponse
|
||||
for _, date := range fillEmptyDays(dates) {
|
||||
resp.Entries = append(resp.Entries, codersdk.DAUEntry{
|
||||
Date: date,
|
||||
Amount: len(respMap[date]),
|
||||
})
|
||||
}
|
||||
|
||||
return resp
|
||||
}
|
||||
|
||||
func countUniqueUsers(rows []database.GetTemplateDAUsRow) int {
|
||||
seen := make(map[uuid.UUID]struct{}, len(rows))
|
||||
for _, row := range rows {
|
||||
@@ -130,10 +153,19 @@ func (c *Cache) refresh(ctx context.Context) error {
|
||||
}
|
||||
|
||||
var (
|
||||
deploymentDAUs = codersdk.DeploymentDAUsResponse{}
|
||||
templateDAUs = make(map[uuid.UUID]codersdk.TemplateDAUsResponse, len(templates))
|
||||
templateUniqueUsers = make(map[uuid.UUID]int)
|
||||
templateAverageBuildTimes = make(map[uuid.UUID]database.GetTemplateAverageBuildTimeRow)
|
||||
)
|
||||
|
||||
rows, err := c.database.GetDeploymentDAUs(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
deploymentDAUs = convertDeploymentDAUResponse(rows)
|
||||
c.deploymentDAUResponses.Store(&deploymentDAUs)
|
||||
|
||||
for _, template := range templates {
|
||||
rows, err := c.database.GetTemplateDAUs(ctx, template.ID)
|
||||
if err != nil {
|
||||
@@ -207,6 +239,11 @@ func (c *Cache) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Cache) DeploymentDAUs() (*codersdk.DeploymentDAUsResponse, bool) {
|
||||
m := c.deploymentDAUResponses.Load()
|
||||
return m, m != nil
|
||||
}
|
||||
|
||||
// TemplateDAUs returns an empty response if the template doesn't have users
|
||||
// or is loading for the first time.
|
||||
func (c *Cache) TemplateDAUs(id uuid.UUID) (*codersdk.TemplateDAUsResponse, bool) {
|
||||
|
||||
Reference in New Issue
Block a user