( ctx context.Context, request *proto.CommitQuotaRequest, )
| 23 | } |
| 24 | |
| 25 | func (c *committer) CommitQuota( |
| 26 | ctx context.Context, request *proto.CommitQuotaRequest, |
| 27 | ) (*proto.CommitQuotaResponse, error) { |
| 28 | jobID, err := uuid.Parse(request.JobId) |
| 29 | if err != nil { |
| 30 | return nil, err |
| 31 | } |
| 32 | |
| 33 | nextBuild, err := c.Database.GetWorkspaceBuildByJobID(ctx, jobID) |
| 34 | if err != nil { |
| 35 | return nil, err |
| 36 | } |
| 37 | |
| 38 | workspace, err := c.Database.GetWorkspaceByID(ctx, nextBuild.WorkspaceID) |
| 39 | if err != nil { |
| 40 | return nil, err |
| 41 | } |
| 42 | |
| 43 | var ( |
| 44 | consumed int64 |
| 45 | budget int64 |
| 46 | permit bool |
| 47 | ) |
| 48 | err = c.Database.InTx(func(s database.Store) error { |
| 49 | var err error |
| 50 | consumed, err = s.GetQuotaConsumedForUser(ctx, database.GetQuotaConsumedForUserParams{ |
| 51 | OwnerID: workspace.OwnerID, |
| 52 | OrganizationID: workspace.OrganizationID, |
| 53 | }) |
| 54 | if err != nil { |
| 55 | return err |
| 56 | } |
| 57 | |
| 58 | budget, err = s.GetQuotaAllowanceForUser(ctx, database.GetQuotaAllowanceForUserParams{ |
| 59 | UserID: workspace.OwnerID, |
| 60 | OrganizationID: workspace.OrganizationID, |
| 61 | }) |
| 62 | if err != nil { |
| 63 | return err |
| 64 | } |
| 65 | |
| 66 | // If the new build will reduce overall quota consumption, then we |
| 67 | // allow it even if the user is over quota. |
| 68 | netIncrease := true |
| 69 | prevBuild, err := s.GetWorkspaceBuildByWorkspaceIDAndBuildNumber(ctx, database.GetWorkspaceBuildByWorkspaceIDAndBuildNumberParams{ |
| 70 | WorkspaceID: workspace.ID, |
| 71 | BuildNumber: nextBuild.BuildNumber - 1, |
| 72 | }) |
| 73 | if err == nil { |
| 74 | netIncrease = request.DailyCost >= prevBuild.DailyCost |
| 75 | c.Log.Debug( |
| 76 | ctx, "previous build cost", |
| 77 | slog.F("prev_cost", prevBuild.DailyCost), |
| 78 | slog.F("next_cost", request.DailyCost), |
| 79 | slog.F("net_increase", netIncrease), |
| 80 | ) |
| 81 | } else if !errors.Is(err, sql.ErrNoRows) { |
| 82 | return err |
nothing calls this directly
no test coverage detected