Skip to content

Commit a20e0b7

Browse files
committed
[server] Delete prebuild records when purging workspaces
1 parent b422b93 commit a20e0b7

File tree

7 files changed

+114
-28
lines changed

7 files changed

+114
-28
lines changed

components/gitpod-db/src/typeorm/entity/db-prebuild-info-entry.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,8 @@ export class DBPrebuildInfo {
3131
})(),
3232
})
3333
info: PrebuildInfo;
34+
35+
// This column triggers the db-sync deletion mechanism. It's not intended for public consumption.
36+
@Column()
37+
deleted?: boolean;
3438
}

components/gitpod-db/src/typeorm/entity/db-prebuilt-workspace.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,8 @@ export class DBPrebuiltWorkspace implements PrebuiltWorkspace {
7777
transformer: Transformer.MAP_BIGINT_TO_NUMBER,
7878
})
7979
statusVersion: number;
80+
81+
// This column triggers the db-sync deletion mechanism. It's not intended for public consumption.
82+
@Column()
83+
deleted?: boolean;
8084
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Copyright (c) 2021 Gitpod GmbH. All rights reserved.
3+
* Licensed under the GNU Affero General Public License (AGPL).
4+
* See License-AGPL.txt in the project root for license information.
5+
*/
6+
7+
import * as prometheusClient from "prom-client";
8+
9+
export function registerDBMetrics(registry: prometheusClient.Registry) {
10+
registry.registerMetric(workspacesPurgedTotal);
11+
registry.registerMetric(prebuildWorkspacesPurgedTotal);
12+
registry.registerMetric(prebuildInfoPurgedTotal);
13+
registry.registerMetric(workspaceInstancePurgedTotal);
14+
}
15+
16+
const workspacesPurgedTotal = new prometheusClient.Counter({
17+
name: "gitpod_server_workspaces_purged_total",
18+
help: "Counter of workspaces hard deleted by periodic gc.",
19+
registers: [prometheusClient.register],
20+
});
21+
22+
export function reportWorkspacePurged(count: number) {
23+
workspacesPurgedTotal.inc(count);
24+
}
25+
26+
const prebuildWorkspacesPurgedTotal = new prometheusClient.Counter({
27+
name: "gitpod_server_prebuild_workspaces_purged_total",
28+
help: "Counter of prebuild workspaces hard deleted by periodic gc.",
29+
registers: [prometheusClient.register],
30+
});
31+
32+
export function reportPrebuiltWorkspacePurged(count: number) {
33+
prebuildWorkspacesPurgedTotal.inc(count);
34+
}
35+
36+
const prebuildInfoPurgedTotal = new prometheusClient.Counter({
37+
name: "gitpod_server_prebuild_info_purged_total",
38+
help: "Counter of prebuild info records hard deleted by periodic gc.",
39+
registers: [prometheusClient.register],
40+
});
41+
42+
export function reportPrebuildInfoPurged(count: number) {
43+
prebuildInfoPurgedTotal.inc(count);
44+
}
45+
46+
const workspaceInstancePurgedTotal = new prometheusClient.Counter({
47+
name: "gitpod_server_workspace_instances_purged_total",
48+
help: "Counter of workspace instances records hard deleted by periodic gc.",
49+
registers: [prometheusClient.register],
50+
});
51+
52+
export function reportWorkspaceInstancePurged(count: number) {
53+
workspaceInstancePurgedTotal.inc(count);
54+
}

components/gitpod-db/src/typeorm/workspace-db-impl.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ import { DBPrebuiltWorkspaceUpdatable } from "./entity/db-prebuilt-workspace-upd
5353
import { BUILTIN_WORKSPACE_PROBE_USER_ID } from "../user-db";
5454
import { DBPrebuildInfo } from "./entity/db-prebuild-info-entry";
5555
import { daysBefore } from "@gitpod/gitpod-protocol/lib/util/timeutil";
56+
import {
57+
reportPrebuildInfoPurged,
58+
reportPrebuiltWorkspacePurged,
59+
reportWorkspaceInstancePurged,
60+
reportWorkspacePurged,
61+
} from "./metrics";
5662

5763
type RawTo<T> = (instance: WorkspaceInstance, ws: Workspace) => T;
5864
interface OrderBy {
@@ -981,8 +987,27 @@ export abstract class AbstractTypeORMWorkspaceDBImpl implements WorkspaceDB {
981987
* around to deleting them.
982988
*/
983989
public async hardDeleteWorkspace(workspaceId: string): Promise<void> {
984-
await (await this.getWorkspaceInstanceRepo()).update({ workspaceId }, { deleted: true });
985-
await (await this.getWorkspaceRepo()).update(workspaceId, { deleted: true });
990+
const prebuild = await this.findPrebuildByWorkspaceID(workspaceId);
991+
if (prebuild !== undefined) {
992+
// There are prebuilds linked to this workspace. We need to delete these first.
993+
const prebuildsDeleted = await (
994+
await this.getPrebuiltWorkspaceRepo()
995+
).update({ id: prebuild.id }, { deleted: true });
996+
reportPrebuiltWorkspacePurged(prebuildsDeleted.affected || 0);
997+
998+
// Delete the d_b_prebuilt_workspace_updatable record?
999+
// await (await this.getPrebuiltWorkspaceUpdatableRepo()).update()
1000+
1001+
const prebuildInfos = await (
1002+
await this.getPrebuildInfoRepo()
1003+
).update({ prebuildId: prebuild.id }, { deleted: true });
1004+
reportPrebuildInfoPurged(prebuildInfos.affected || 0);
1005+
}
1006+
const instances = await (await this.getWorkspaceInstanceRepo()).update({ workspaceId }, { deleted: true });
1007+
reportWorkspaceInstancePurged(instances.affected || 0);
1008+
1009+
const workspaces = await (await this.getWorkspaceRepo()).update(workspaceId, { deleted: true });
1010+
reportWorkspacePurged(workspaces.affected || 0);
9861011
}
9871012

9881013
public async findAllWorkspaces(

components/server/ee/src/monitoring-endpoint-ee.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,21 @@ import { WorkspaceHealthMonitoring } from "./workspace/workspace-health-monitori
99
import { TraceContext } from "@gitpod/gitpod-protocol/lib/util/tracing";
1010
import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
1111
import { injectable, inject } from "inversify";
12-
import { register } from "../../src/prometheus-metrics";
12+
import { register, registerServerMetrics } from "../../src/prometheus-metrics";
13+
import * as prometheusClient from "prom-client";
14+
import { registerDBMetrics } from "@gitpod/gitpod-db/lib/metrics";
1315

1416
@injectable()
1517
export class MonitoringEndpointsAppEE extends WorkspaceHealthMonitoring {
1618
@inject(WorkspaceHealthMonitoring) protected readonly workspaceHealthMonitoring: WorkspaceHealthMonitoring;
1719

1820
public create(): express.Application {
21+
const registry = prometheusClient.register;
22+
23+
prometheusClient.collectDefaultMetrics({ register });
24+
registerDBMetrics(registry);
25+
registerServerMetrics(registry);
26+
1927
const monApp = express();
2028
monApp.get("/metrics", async (req, res) => {
2129
try {

components/server/src/prometheus-metrics.ts

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,26 @@ import * as prometheusClient from "prom-client";
1010
prometheusClient.collectDefaultMetrics();
1111
export const register = prometheusClient.register;
1212

13+
export function registerServerMetrics(registry: prometheusClient.Registry) {
14+
registry.registerMetric(loginCounter);
15+
registry.registerMetric(apiConnectionCounter);
16+
registry.registerMetric(apiConnectionClosedCounter);
17+
registry.registerMetric(apiCallCounter);
18+
registry.registerMetric(apiCallDurationHistogram);
19+
registry.registerMetric(apiCallUserCounter);
20+
registry.registerMetric(httpRequestTotal);
21+
registry.registerMetric(httpRequestDuration);
22+
registry.registerMetric(messagebusTopicReads);
23+
registry.registerMetric(gitpodVersionInfo);
24+
registry.registerMetric(instanceStartsSuccessTotal);
25+
registry.registerMetric(instanceStartsFailedTotal);
26+
registry.registerMetric(prebuildsStartedTotal);
27+
}
28+
1329
const loginCounter = new prometheusClient.Counter({
1430
name: "gitpod_server_login_requests_total",
1531
help: "Total amount of login requests",
1632
labelNames: ["status", "auth_host"],
17-
registers: [prometheusClient.register],
1833
});
1934

2035
export function increaseLoginCounter(status: string, auth_host: string) {
@@ -27,7 +42,6 @@ export function increaseLoginCounter(status: string, auth_host: string) {
2742
const apiConnectionCounter = new prometheusClient.Counter({
2843
name: "gitpod_server_api_connections_total",
2944
help: "Total amount of established API connections",
30-
registers: [prometheusClient.register],
3145
});
3246

3347
export function increaseApiConnectionCounter() {
@@ -37,7 +51,6 @@ export function increaseApiConnectionCounter() {
3751
const apiConnectionClosedCounter = new prometheusClient.Counter({
3852
name: "gitpod_server_api_connections_closed_total",
3953
help: "Total amount of closed API connections",
40-
registers: [prometheusClient.register],
4154
});
4255

4356
export function increaseApiConnectionClosedCounter() {
@@ -48,7 +61,6 @@ const apiCallCounter = new prometheusClient.Counter({
4861
name: "gitpod_server_api_calls_total",
4962
help: "Total amount of API calls per method",
5063
labelNames: ["method", "statusCode"],
51-
registers: [prometheusClient.register],
5264
});
5365

5466
export function increaseApiCallCounter(method: string, statusCode: number) {
@@ -60,7 +72,6 @@ export const apiCallDurationHistogram = new prometheusClient.Histogram({
6072
help: "Duration of API calls in seconds",
6173
labelNames: ["method"],
6274
buckets: [0.1, 0.5, 1, 5, 10, 15, 30],
63-
registers: [prometheusClient.register],
6475
});
6576

6677
export function observeAPICallsDuration(method: string, duration: number) {
@@ -71,7 +82,6 @@ const apiCallUserCounter = new prometheusClient.Counter({
7182
name: "gitpod_server_api_calls_user_total",
7283
help: "Total amount of API calls per user",
7384
labelNames: ["method", "user"],
74-
registers: [prometheusClient.register],
7585
});
7686

7787
export function increaseApiCallUserCounter(method: string, user: string) {
@@ -82,7 +92,6 @@ const httpRequestTotal = new prometheusClient.Counter({
8292
name: "gitpod_server_http_requests_total",
8393
help: "Total amount of HTTP requests per express route",
8494
labelNames: ["method", "route", "statusCode"],
85-
registers: [prometheusClient.register],
8695
});
8796

8897
export function increaseHttpRequestCounter(method: string, route: string, statusCode: number) {
@@ -94,7 +103,6 @@ const httpRequestDuration = new prometheusClient.Histogram({
94103
help: "Duration of HTTP requests in seconds",
95104
labelNames: ["method", "route", "statusCode"],
96105
buckets: [0.01, 0.05, 0.1, 0.5, 1, 5, 10],
97-
registers: [prometheusClient.register],
98106
});
99107

100108
export function observeHttpRequestDuration(
@@ -110,7 +118,6 @@ const messagebusTopicReads = new prometheusClient.Counter({
110118
name: "gitpod_server_topic_reads_total",
111119
help: "The amount of reads from messagebus topics.",
112120
labelNames: ["topic"],
113-
registers: [prometheusClient.register],
114121
});
115122

116123
export function increaseMessagebusTopicReads(topic: string) {
@@ -123,7 +130,6 @@ const gitpodVersionInfo = new prometheusClient.Gauge({
123130
name: "gitpod_version_info",
124131
help: "Gitpod's version",
125132
labelNames: ["gitpod_version"],
126-
registers: [prometheusClient.register],
127133
});
128134

129135
export function setGitpodVersion(gitpod_version: string) {
@@ -134,7 +140,6 @@ const instanceStartsSuccessTotal = new prometheusClient.Counter({
134140
name: "gitpod_server_instance_starts_success_total",
135141
help: "Total amount of successfully performed instance starts",
136142
labelNames: ["retries"],
137-
registers: [prometheusClient.register],
138143
});
139144

140145
export function increaseSuccessfulInstanceStartCounter(retries: number = 0) {
@@ -145,7 +150,6 @@ const instanceStartsFailedTotal = new prometheusClient.Counter({
145150
name: "gitpod_server_instance_starts_failed_total",
146151
help: "Total amount of failed performed instance starts",
147152
labelNames: ["reason"],
148-
registers: [prometheusClient.register],
149153
});
150154

151155
export type FailedInstanceStartReason =
@@ -160,19 +164,8 @@ export function increaseFailedInstanceStartCounter(reason: FailedInstanceStartRe
160164
const prebuildsStartedTotal = new prometheusClient.Counter({
161165
name: "gitpod_prebuilds_started_total",
162166
help: "Counter of total prebuilds started.",
163-
registers: [prometheusClient.register],
164167
});
165168

166169
export function increasePrebuildsStartedCounter() {
167170
prebuildsStartedTotal.inc();
168171
}
169-
170-
const workspacesPurgedTotal = new prometheusClient.Counter({
171-
name: "gitpod_server_workspaces_purged_total",
172-
help: "Counter of workspaces hard deleted by periodic job running on server.",
173-
registers: [prometheusClient.register],
174-
});
175-
176-
export function reportWorkspacePurged() {
177-
workspacesPurgedTotal.inc();
178-
}

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import { TraceContext } from "@gitpod/gitpod-protocol/lib/util/tracing";
1919
import { WorkspaceManagerClientProvider } from "@gitpod/ws-manager/lib/client-provider";
2020
import { DeleteVolumeSnapshotRequest } from "@gitpod/ws-manager/lib";
2121
import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
22-
import { reportWorkspacePurged } from "../prometheus-metrics";
2322

2423
@injectable()
2524
export class WorkspaceDeletionService {
@@ -57,7 +56,6 @@ export class WorkspaceDeletionService {
5756
public async hardDeleteWorkspace(ctx: TraceContext, workspaceId: string): Promise<void> {
5857
await this.db.trace(ctx).hardDeleteWorkspace(workspaceId);
5958
log.info(`Purged Workspace ${workspaceId} and all WorkspaceInstances for this workspace`, { workspaceId });
60-
reportWorkspacePurged();
6159
}
6260

6361
/**

0 commit comments

Comments
 (0)