-
Notifications
You must be signed in to change notification settings - Fork 1.3k
[ws-gc] WS soft deletion improvements #20271
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
01661f9
fa953e8
c7d01ea
c428b1e
97c0929
2947014
440a4c4
13e1a76
39065c7
00af0fe
8442491
bb26298
743ae10
f286566
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -223,8 +223,8 @@ export class WorkspaceService { | |
| ); | ||
| throw err; | ||
| } | ||
| this.asyncUpdateDeletionEligabilityTime(user.id, workspace.id); | ||
| this.asyncUpdateDeletionEligabilityTimeForUsedPrebuild(user.id, workspace); | ||
| this.asyncUpdateDeletionEligibilityTime(user.id, workspace.id, true); | ||
| this.asyncUpdateDeletionEligibilityTimeForUsedPrebuild(user.id, workspace); | ||
| if (project && workspace.type === "regular") { | ||
| this.asyncHandleUpdatePrebuildTriggerStrategy({ ctx, project, workspace, user }); | ||
| this.asyncStartPrebuild({ ctx, project, workspace, user }); | ||
|
|
@@ -248,7 +248,7 @@ export class WorkspaceService { | |
| const res = await this.db.find({ | ||
| limit: 20, | ||
| ...options, | ||
| userId, // gpl: We probably want to removed this limitation in the future, butkeeping the old behavior for now due to focus on FGA | ||
| userId, // gpl: We probably want to removed this limitation in the future, but keeping the old behavior for now due to focus on FGA | ||
| includeHeadless: false, | ||
| }); | ||
|
|
||
|
|
@@ -375,7 +375,7 @@ export class WorkspaceService { | |
| return; | ||
| } | ||
| await this.workspaceStarter.stopWorkspaceInstance({}, instance.id, instance.region, reason, policy); | ||
| this.asyncUpdateDeletionEligabilityTime(userId, workspaceId); | ||
| this.asyncUpdateDeletionEligibilityTime(userId, workspaceId, true); | ||
| } | ||
|
|
||
| public async stopRunningWorkspacesForUser( | ||
|
|
@@ -396,21 +396,21 @@ export class WorkspaceService { | |
| reason, | ||
| policy, | ||
| ); | ||
| this.asyncUpdateDeletionEligabilityTime(userId, info.workspace.id); | ||
| this.asyncUpdateDeletionEligibilityTime(userId, info.workspace.id, false); | ||
| }), | ||
| ); | ||
| return infos.map((instance) => instance.workspace); | ||
| } | ||
|
|
||
| private asyncUpdateDeletionEligabilityTimeForUsedPrebuild(userId: string, workspace: Workspace): void { | ||
| private asyncUpdateDeletionEligibilityTimeForUsedPrebuild(userId: string, workspace: Workspace): void { | ||
| (async () => { | ||
| if (WithPrebuild.is(workspace.context) && workspace.context.prebuildWorkspaceId) { | ||
| // mark the prebuild active | ||
| const prebuiltWorkspace = await this.db.findPrebuiltWorkspaceById( | ||
| workspace.context.prebuildWorkspaceId, | ||
| ); | ||
| if (prebuiltWorkspace?.buildWorkspaceId) { | ||
| await this.updateDeletionEligabilityTime(userId, prebuiltWorkspace?.buildWorkspaceId, true); | ||
| await this.updateDeletionEligibilityTime(userId, prebuiltWorkspace?.buildWorkspaceId, true); | ||
| } | ||
| } | ||
| })().catch((err) => | ||
|
|
@@ -515,20 +515,20 @@ export class WorkspaceService { | |
| ); | ||
| } | ||
|
|
||
| private asyncUpdateDeletionEligabilityTime(userId: string, workspaceId: string): void { | ||
| this.updateDeletionEligabilityTime(userId, workspaceId).catch((err) => | ||
| private asyncUpdateDeletionEligibilityTime(userId: string, workspaceId: string, activeNow?: boolean): void { | ||
| this.updateDeletionEligibilityTime(userId, workspaceId, activeNow).catch((err) => | ||
| log.error({ userId, workspaceId }, "Failed to update deletion eligibility time", err), | ||
| ); | ||
| } | ||
|
|
||
| /** | ||
| * Sets the deletionEligibilityTime of the workspace, depending on the current state of the workspace and the configuration. | ||
| * | ||
| * @param userId sets the | ||
| * @param workspaceId | ||
| * @param userId the user to act as | ||
| * @param workspaceId the workspace to update | ||
| * @returns | ||
| */ | ||
| async updateDeletionEligabilityTime(userId: string, workspaceId: string, activeNow = false): Promise<void> { | ||
| async updateDeletionEligibilityTime(userId: string, workspaceId: string, activeNow = false): Promise<void> { | ||
| try { | ||
| let daysToLive = this.config.workspaceGarbageCollection?.minAgeDays || 14; | ||
| const daysToLiveForPrebuilds = this.config.workspaceGarbageCollection?.minAgePrebuildDays || 7; | ||
|
|
@@ -561,6 +561,12 @@ export class WorkspaceService { | |
| daysToLive = daysToLive * 2; | ||
| } | ||
| deletionEligibilityTime.setDate(deletionEligibilityTime.getDate() + daysToLive); | ||
| if (new Date() > deletionEligibilityTime) { | ||
geropl marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| log.warn({ userId, workspaceId }, "Prevented setting deletion eligibility time in the past", { | ||
|
||
| deletionEligibilityTime: deletionEligibilityTime.toISOString(), | ||
| }); | ||
| return; | ||
| } | ||
| await this.db.updatePartial(workspaceId, { | ||
| deletionEligibilityTime: deletionEligibilityTime.toISOString(), | ||
| }); | ||
|
|
@@ -819,7 +825,7 @@ export class WorkspaceService { | |
|
|
||
| // at this point we're about to actually start a new workspace | ||
| const result = await this.workspaceStarter.startWorkspace(ctx, workspace, user, await projectPromise, options); | ||
| this.asyncUpdateDeletionEligabilityTime(user.id, workspaceId); | ||
| this.asyncUpdateDeletionEligibilityTime(user.id, workspaceId, true); | ||
| return result; | ||
| } | ||
|
|
||
|
|
@@ -928,7 +934,7 @@ export class WorkspaceService { | |
|
|
||
| const workspace = await this.doGetWorkspace(userId, workspaceId); | ||
| instance = await this.db.updateInstancePartial(instance.id, { gitStatus }); | ||
| await this.updateDeletionEligabilityTime(userId, workspaceId); | ||
| await this.updateDeletionEligibilityTime(userId, workspaceId, true); | ||
| await this.publisher.publishInstanceUpdate({ | ||
| instanceID: instance.id, | ||
| ownerID: workspace.ownerId, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to align this with
findWorkspacesForPurgingby converting from a raw SQL statement, but maybe it's too out of scope here. I'm curious if anyone has thoughts about itThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at the "async predicate" which looks way too much like a join in disguise, let' snot do this right now. 👍 🙃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WDYT about the readability of this with
13e1a76(#20271)? I tried putting everything into a single query and think that it makes a bit more sense.The benefit of using this join is not too big though so I'm happy to revert if you think it's not that helpful.