diff --git a/coderd/insights.go b/coderd/insights.go index 99f87e65eb1d5..80865b9287ec6 100644 --- a/coderd/insights.go +++ b/coderd/insights.go @@ -8,6 +8,7 @@ import ( "github.com/google/uuid" "golang.org/x/exp/slices" + "golang.org/x/sync/errgroup" "golang.org/x/xerrors" "github.com/coder/coder/v2/coderd/database" @@ -190,14 +191,18 @@ func (api *API) insightsTemplates(rw http.ResponseWriter, r *http.Request) { var usage database.GetTemplateInsightsRow var appUsage []database.GetTemplateAppInsightsRow var dailyUsage []database.GetTemplateDailyInsightsRow + var parameterRows []database.GetTemplateParameterInsightsRow - // Use a transaction to ensure that we get consistent data between - // the full and interval report. - err := api.Database.InTx(func(tx database.Store) error { - var err error + eg, egCtx := errgroup.WithContext(ctx) + eg.SetLimit(4) + // The following insights data queries have a theoretical chance to be + // inconsistent between eachother when looking at "today", however, the + // overhead from a transaction is not worth it. + eg.Go(func() error { + var err error if interval != "" { - dailyUsage, err = tx.GetTemplateDailyInsights(ctx, database.GetTemplateDailyInsightsParams{ + dailyUsage, err = api.Database.GetTemplateDailyInsights(egCtx, database.GetTemplateDailyInsightsParams{ StartTime: startTime, EndTime: endTime, TemplateIDs: templateIDs, @@ -206,8 +211,11 @@ func (api *API) insightsTemplates(rw http.ResponseWriter, r *http.Request) { return xerrors.Errorf("get template daily insights: %w", err) } } - - usage, err = tx.GetTemplateInsights(ctx, database.GetTemplateInsightsParams{ + return nil + }) + eg.Go(func() error { + var err error + usage, err = api.Database.GetTemplateInsights(egCtx, database.GetTemplateInsightsParams{ StartTime: startTime, EndTime: endTime, TemplateIDs: templateIDs, @@ -215,8 +223,11 @@ func (api *API) insightsTemplates(rw http.ResponseWriter, r *http.Request) { if err != nil { return xerrors.Errorf("get template insights: %w", err) } - - appUsage, err = tx.GetTemplateAppInsights(ctx, database.GetTemplateAppInsightsParams{ + return nil + }) + eg.Go(func() error { + var err error + appUsage, err = api.Database.GetTemplateAppInsights(egCtx, database.GetTemplateAppInsightsParams{ StartTime: startTime, EndTime: endTime, TemplateIDs: templateIDs, @@ -224,9 +235,25 @@ func (api *API) insightsTemplates(rw http.ResponseWriter, r *http.Request) { if err != nil { return xerrors.Errorf("get template app insights: %w", err) } + return nil + }) + // Template parameter insights have no risk of inconsistency with the other + // insights. + eg.Go(func() error { + var err error + parameterRows, err = api.Database.GetTemplateParameterInsights(ctx, database.GetTemplateParameterInsightsParams{ + StartTime: startTime, + EndTime: endTime, + TemplateIDs: templateIDs, + }) + if err != nil { + return xerrors.Errorf("get template parameter insights: %w", err) + } return nil - }, nil) + }) + + err := eg.Wait() if httpapi.Is404Error(err) { httpapi.ResourceNotFound(rw) return @@ -239,21 +266,6 @@ func (api *API) insightsTemplates(rw http.ResponseWriter, r *http.Request) { return } - // Template parameter insights have no risk of inconsistency with the other - // insights, so we don't need to perform this in a transaction. - parameterRows, err := api.Database.GetTemplateParameterInsights(ctx, database.GetTemplateParameterInsightsParams{ - StartTime: startTime, - EndTime: endTime, - TemplateIDs: templateIDs, - }) - if err != nil { - httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ - Message: "Internal error fetching template parameter insights.", - Detail: err.Error(), - }) - return - } - parametersUsage, err := db2sdk.TemplateInsightsParameters(parameterRows) if err != nil { httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: