mirror of https://github.com/coder/coder.git
fix(coderd): parallelize queries to improve template insights performance (#9275)
This commit is contained in:
parent
d180df1fd5
commit
8bfa312905
|
@ -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 {
|
||||
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
|
||||
}, 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
|
||||
})
|
||||
|
||||
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{
|
||||
|
|
Loading…
Reference in New Issue