mirror of
https://github.com/gitpod-io/gitpod.git
synced 2025-12-08 17:36:30 +00:00
83 lines
3.7 KiB
TypeScript
83 lines
3.7 KiB
TypeScript
/**
|
|
* Copyright (c) 2021 Gitpod GmbH. All rights reserved.
|
|
* Licensed under the GNU Affero General Public License (AGPL).
|
|
* See License-AGPL.txt in the project root for license information.
|
|
*/
|
|
|
|
import { inject, injectable } from "inversify";
|
|
import { WorkspaceDB } from "@gitpod/gitpod-db/lib/workspace-db";
|
|
import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
|
|
import { RunningWorkspaceInfo } from "@gitpod/gitpod-protocol/lib";
|
|
import { MessageBusIntegration } from "./messagebus-integration";
|
|
import { Configuration } from "./config";
|
|
|
|
@injectable()
|
|
export class MetaInstanceController {
|
|
@inject(Configuration)
|
|
protected readonly config: Configuration;
|
|
|
|
@inject(MessageBusIntegration)
|
|
protected readonly messagebus: MessageBusIntegration;
|
|
|
|
@inject(WorkspaceDB)
|
|
protected readonly workspaceDB: WorkspaceDB;
|
|
|
|
protected async checkAndStopWorkspaces() {
|
|
const instances = await this.workspaceDB.findRunningInstancesWithWorkspaces(this.config.installation, undefined, true);
|
|
|
|
await Promise.all(instances.map(async (instance: RunningWorkspaceInfo) => {
|
|
const logContext = { instanceId: instance.latestInstance.id };
|
|
|
|
try {
|
|
const now = Date.now();
|
|
const creationTime = new Date(instance.latestInstance.creationTime).getTime();
|
|
const stoppingTime = new Date(instance.latestInstance.stoppingTime ?? now).getTime(); // stoppingTime only set if entered stopping state
|
|
const timedOutInPreparing = now >= creationTime + (this.config.timeouts.preparingPhaseSeconds * 1000);
|
|
const timedOutInStopping = now >= stoppingTime + (this.config.timeouts.stoppingPhaseSeconds * 1000);
|
|
const timedOutInUnknown = now >= creationTime + (this.config.timeouts.unknownPhaseSeconds * 1000);
|
|
const currentPhase = instance.latestInstance.status.phase;
|
|
|
|
// log.debug(logContext, 'MetaInstanceController: Checking for workspaces to stop', {
|
|
// creationTime,
|
|
// stoppingTime,
|
|
// timedOutInPreparing,
|
|
// timedOutInStopping,
|
|
// timedOutInUnknown,
|
|
// currentPhase
|
|
// });
|
|
|
|
if (
|
|
(currentPhase === 'preparing' && timedOutInPreparing) ||
|
|
(currentPhase === 'stopping' && timedOutInStopping) ||
|
|
(currentPhase === 'unknown' && timedOutInUnknown)
|
|
) {
|
|
log.debug(logContext, 'MetaInstanceController: Setting workspace instance to stopped', {
|
|
creationTime,
|
|
currentPhase
|
|
});
|
|
|
|
const nowISO = new Date(now).toISOString();
|
|
instance.latestInstance.stoppingTime = nowISO;
|
|
instance.latestInstance.stoppedTime = nowISO;
|
|
instance.latestInstance.status.phase = 'stopped';
|
|
|
|
await this.workspaceDB.storeInstance(instance.latestInstance);
|
|
await this.messagebus.notifyOnInstanceUpdate({}, instance.workspace.ownerId, instance.latestInstance);
|
|
}
|
|
} catch (err) {
|
|
log.warn(logContext, 'MetaInstanceController: Error whilst stopping workspace instance', err);
|
|
}
|
|
}));
|
|
}
|
|
|
|
public start() {
|
|
log.info('MetaInstanceController: Starting interval to check for workspaces to stop', {
|
|
interval: this.config.timeouts.metaInstanceCheckIntervalSeconds
|
|
});
|
|
|
|
setInterval(() => {
|
|
this.checkAndStopWorkspaces();
|
|
}, this.config.timeouts.metaInstanceCheckIntervalSeconds * 1000);
|
|
}
|
|
}
|