Skip to content

Commit 969c030

Browse files
committed
Move LazyOrganizationService to UBP entitlement service to get rid of circ. dep. errs
1 parent 7188a5c commit 969c030

File tree

4 files changed

+19
-16
lines changed

4 files changed

+19
-16
lines changed

components/server/src/billing/entitlement-service-ubp.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import {
1515
BillingTier,
1616
MAX_PARALLEL_WORKSPACES_PAID,
1717
MAX_PARALLEL_WORKSPACES_FREE,
18-
OrganizationSettings,
1918
} from "@gitpod/gitpod-protocol";
2019
import { AttributionId } from "@gitpod/gitpod-protocol/lib/attribution";
2120
import { inject, injectable } from "inversify";
@@ -24,6 +23,10 @@ import { CostCenter_BillingStrategy } from "@gitpod/usage-api/lib/usage/v1/usage
2423
import { UsageService } from "../orgs/usage-service";
2524
import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
2625
import { VerificationService } from "../auth/verification-service";
26+
import type { OrganizationService } from "../orgs/organization-service";
27+
28+
export const LazyOrganizationService = Symbol("LazyOrganizationService");
29+
export type LazyOrganizationService = () => OrganizationService;
2730

2831
/**
2932
* EntitlementService implementation for Usage-Based Pricing (UBP)
@@ -33,13 +36,13 @@ export class EntitlementServiceUBP implements EntitlementService {
3336
constructor(
3437
@inject(UsageService) private readonly usageService: UsageService,
3538
@inject(VerificationService) private readonly verificationService: VerificationService,
39+
@inject(LazyOrganizationService) private readonly organizationService: LazyOrganizationService,
3640
) {}
3741

3842
async mayStartWorkspace(
3943
user: User,
4044
organizationId: string,
4145
runningInstances: Promise<WorkspaceInstance[]>,
42-
organizationSettings?: OrganizationSettings,
4346
): Promise<MayStartWorkspaceResult> {
4447
const verification = await this.verificationService.needsVerification(user);
4548
if (verification) {
@@ -49,7 +52,10 @@ export class EntitlementServiceUBP implements EntitlementService {
4952
}
5053

5154
const hasHitParallelWorkspaceLimit = async (): Promise<HitParallelWorkspaceLimit | undefined> => {
52-
const maxParallelRunningWorkspaces = organizationSettings?.maxParallelRunningWorkspaces;
55+
const { maxParallelRunningWorkspaces } = await this.organizationService().getSettings(
56+
user.id,
57+
organizationId,
58+
);
5359
const planAllowance = await this.getMaxParallelWorkspaces(user.id, organizationId);
5460
const max = maxParallelRunningWorkspaces
5561
? Math.min(planAllowance, maxParallelRunningWorkspaces)

components/server/src/billing/entitlement-service.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,13 @@ import {
1212
WORKSPACE_LIFETIME_LONG,
1313
MAX_PARALLEL_WORKSPACES_FREE,
1414
MAX_PARALLEL_WORKSPACES_PAID,
15-
OrganizationSettings,
1615
} from "@gitpod/gitpod-protocol";
1716
import { AttributionId } from "@gitpod/gitpod-protocol/lib/attribution";
1817
import { BillingTier } from "@gitpod/gitpod-protocol/lib/protocol";
1918
import { inject, injectable } from "inversify";
2019
import { BillingModes } from "./billing-mode";
21-
import { EntitlementServiceUBP } from "./entitlement-service-ubp";
20+
import { EntitlementServiceUBP, LazyOrganizationService } from "./entitlement-service-ubp";
2221
import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
23-
import type { OrganizationService } from "../orgs/organization-service";
24-
25-
export const LazyOrganizationService = Symbol("LazyOrganizationService");
26-
export type LazyOrganizationService = () => OrganizationService;
2722

2823
export interface MayStartWorkspaceResult {
2924
hitParallelWorkspaceLimit?: HitParallelWorkspaceLimit;
@@ -53,7 +48,6 @@ export interface EntitlementService {
5348
user: User,
5449
organizationId: string,
5550
runningInstances: Promise<WorkspaceInstance[]>,
56-
organizationSettings?: OrganizationSettings,
5751
): Promise<MayStartWorkspaceResult>;
5852

5953
/**
@@ -118,7 +112,6 @@ export class EntitlementServiceImpl implements EntitlementService {
118112
user: User,
119113
organizationId: string,
120114
runningInstances: Promise<WorkspaceInstance[]>,
121-
organizationSettings?: OrganizationSettings,
122115
): Promise<MayStartWorkspaceResult> {
123116
try {
124117
const billingMode = await this.billingModes.getBillingMode(user.id, organizationId);
@@ -127,6 +120,7 @@ export class EntitlementServiceImpl implements EntitlementService {
127120
switch (billingMode.mode) {
128121
case "none":
129122
// the default limit is MAX_PARALLEL_WORKSPACES_PAID, but organizations can set their own different limit
123+
// we use || here because the default value is 0 and we want to use the default limit if the organization limit is not set
130124
const maxParallelRunningWorkspaces =
131125
organizationSettings.maxParallelRunningWorkspaces || MAX_PARALLEL_WORKSPACES_PAID;
132126
const current = (await runningInstances).filter((i) => i.status.phase !== "preparing").length;
@@ -141,7 +135,7 @@ export class EntitlementServiceImpl implements EntitlementService {
141135

142136
return {};
143137
case "usage-based":
144-
return this.ubp.mayStartWorkspace(user, organizationId, runningInstances, organizationSettings);
138+
return this.ubp.mayStartWorkspace(user, organizationId, runningInstances);
145139
default:
146140
throw new Error("Unsupported billing mode: " + (billingMode as any).mode); // safety net
147141
}

components/server/src/container-module.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ import { RelationshipUpdateJob } from "./authorization/relationship-updater-job"
5454
import { SpiceDBClientProvider, spiceDBConfigFromEnv } from "./authorization/spicedb";
5555
import { createSpiceDBAuthorizer } from "./authorization/spicedb-authorizer";
5656
import { BillingModes } from "./billing/billing-mode";
57-
import { EntitlementService, EntitlementServiceImpl, LazyOrganizationService } from "./billing/entitlement-service";
58-
import { EntitlementServiceUBP } from "./billing/entitlement-service-ubp";
57+
import { EntitlementService, EntitlementServiceImpl } from "./billing/entitlement-service";
58+
import { EntitlementServiceUBP, LazyOrganizationService } from "./billing/entitlement-service-ubp";
5959
import { StripeService } from "./billing/stripe-service";
6060
import { CodeSyncService } from "./code-sync/code-sync-service";
6161
import { Config, ConfigFile } from "./config";

components/server/src/workspace/workspace-service.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -893,10 +893,13 @@ export class WorkspaceService {
893893
},
894894
);
895895
}
896-
if (!!result.hitParallelWorkspaceLimit) {
896+
if (result.hitParallelWorkspaceLimit) {
897+
const { max } = result.hitParallelWorkspaceLimit;
897898
throw new ApplicationError(
898899
ErrorCodes.TOO_MANY_RUNNING_WORKSPACES,
899-
`You cannot run more than ${result.hitParallelWorkspaceLimit.max} workspaces at the same time. Please stop a workspace before starting another one.`,
900+
`You cannot run more than ${max} workspace${
901+
max === 1 ? "" : "s"
902+
} at the same time. Please stop a workspace before starting another one.`,
900903
);
901904
}
902905
}

0 commit comments

Comments
 (0)