Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/ws-manager-bridge/src/app-cluster-instance-controller.ts
2498 views
1
/**
2
* Copyright (c) 2022 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 { WorkspaceDB } from "@gitpod/gitpod-db/lib/workspace-db";
8
import { Disposable, DisposableCollection } from "@gitpod/gitpod-protocol";
9
import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
10
import { repeat } from "@gitpod/gitpod-protocol/lib/util/repeat";
11
import { TraceContext } from "@gitpod/gitpod-protocol/lib/util/tracing";
12
import { inject, injectable } from "inversify";
13
import { Configuration } from "./config";
14
import { WorkspaceInstanceController } from "./workspace-instance-controller";
15
16
/**
17
* The WorkspaceInstance lifecycle is split between application clusters and workspace clusters on the transition from
18
* pending/building -> starting (cmp. WorkspacePhases here:
19
* https://github.com/gitpod-io/gitpod/blob/008ea3fadc89d4817cf3effc8a5b30eaf469fb1c/components/gitpod-protocol/src/workspace-instance.ts#L111).
20
*
21
* Before the transition, WorkspaceInstances belong to the respective app cluster, denoted by "instance.region === 'eu02'", for exmaple.
22
* After a WorkspaceInstance has been moved over to a workspace cluster, that moved "ownership" is reflected in said field.
23
* We maintain a constant connection (called "bridge") to all workspace clusters to be able to keep reality (workspace
24
* side) in sync with what we have in our DB/forward to clients.
25
*
26
* This class is meant to take the same responsibility for all WorkspaceInstances that have not (yet) been passed over
27
* to a workspace cluster for whatever reason. Here's a list of examples, prefixed by phase:
28
* - "preparing": failed cleanup after failed call to wsManager.StartWorkspace
29
* - "building": failed cleanup after failed image-build (which is still controlled by the application cluster,
30
* although that might change in the future)
31
*/
32
@injectable()
33
export class AppClusterWorkspaceInstancesController implements Disposable {
34
constructor(
35
@inject(Configuration) private readonly config: Configuration,
36
@inject(WorkspaceDB) private readonly workspaceDb: WorkspaceDB,
37
@inject(WorkspaceInstanceController)
38
private readonly workspaceInstanceController: WorkspaceInstanceController,
39
) {}
40
41
private readonly dispoables = new DisposableCollection();
42
43
public async start() {
44
const disposable = repeat(
45
async () => this.controlAppClusterManagedWorkspaceInstances(),
46
this.config.controllerIntervalSeconds * 1000,
47
);
48
this.dispoables.push(disposable);
49
}
50
51
private async controlAppClusterManagedWorkspaceInstances() {
52
const appClusterInstallation = this.config.installation;
53
54
const span = TraceContext.startSpan("controlAppClusterManagedWorkspaceInstances");
55
const ctx = { span };
56
try {
57
log.info("Controlling app cluster instances", { installation: appClusterInstallation });
58
59
const notStoppedInstances = await this.workspaceDb.findRunningInstancesWithWorkspaces(
60
appClusterInstallation,
61
undefined,
62
false,
63
);
64
await this.workspaceInstanceController.controlNotStoppedAppClusterManagedInstanceTimeouts(
65
ctx,
66
notStoppedInstances,
67
appClusterInstallation,
68
);
69
70
log.info("Done controlling app cluster instances", {
71
installation: appClusterInstallation,
72
instancesCount: notStoppedInstances.length,
73
});
74
} catch (err) {
75
log.error("Error controlling app cluster instances", err, {
76
installation: appClusterInstallation,
77
});
78
TraceContext.setError(ctx, err);
79
} finally {
80
span.finish();
81
}
82
}
83
84
public dispose() {
85
this.dispoables.dispose();
86
}
87
}
88
89