Skip to content

Commit 13e1a76

Browse files
committed
No more async filter predicates
1 parent 440a4c4 commit 13e1a76

File tree

1 file changed

+22
-14
lines changed

1 file changed

+22
-14
lines changed

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

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -488,35 +488,43 @@ export class TypeORMWorkspaceDBImpl extends TransactionalDBImpl<WorkspaceDB> imp
488488
limit: number = 100,
489489
type: WorkspaceType = "regular",
490490
): Promise<WorkspaceOwnerAndDeletionEligibility[]> {
491-
// we do not allow to run this with a future date
492491
if (cutOffDate > new Date()) {
493492
throw new Error("cutOffDate must not be in the future, was: " + cutOffDate.toISOString());
494493
}
495494
const workspaceRepo = await this.getWorkspaceRepo();
496495
const qb = workspaceRepo
497496
.createQueryBuilder("ws")
498-
.select(["ws.id", "ws.ownerId", "ws.deletionEligibilityTime"])
497+
.leftJoinAndMapOne(
498+
"ws.latestInstance",
499+
DBWorkspaceInstance,
500+
"wsi",
501+
`wsi.id = (
502+
SELECT i.id
503+
FROM d_b_workspace_instance AS i
504+
WHERE i.workspaceId = ws.id
505+
ORDER BY i.creationTime DESC
506+
LIMIT 1
507+
)`,
508+
)
509+
.select(["ws.id", "ws.ownerId", "ws.deletionEligibilityTime", "wsi.id", "wsi.status"])
499510
.where("ws.deleted = :deleted", { deleted: 0 })
500511
.andWhere("ws.type = :type", { type })
501512
.andWhere("ws.softDeleted IS NULL")
502513
.andWhere("ws.softDeletedTime = ''")
503514
.andWhere("ws.pinned = :pinned", { pinned: 0 })
504515
.andWhere("ws.deletionEligibilityTime != ''")
505516
.andWhere("ws.deletionEligibilityTime < :cutOffDate", { cutOffDate: cutOffDate.toISOString() })
517+
// we don't want to delete workspaces that are active
518+
.andWhere(
519+
new Brackets((qb) => {
520+
qb.where("wsi.id IS NULL").orWhere("JSON_UNQUOTE(wsi.status->>'$.phase') = :stoppedStatus", {
521+
stoppedStatus: "stopped",
522+
});
523+
}),
524+
)
506525
.limit(limit);
507526

508-
const results: WorkspaceOwnerAndDeletionEligibility[] = await qb.getMany();
509-
510-
// hack to have an async filter predicate
511-
const filtered = await Promise.all(
512-
results.map(async (ws) => {
513-
// we don't want to delete workspaces that have a running instance
514-
const latestInstance = await this.findRunningInstance(ws.id);
515-
return { ws, keep: latestInstance === undefined };
516-
}),
517-
);
518-
519-
return filtered.filter((result) => result.keep).map((result) => result.ws);
527+
return qb.getMany();
520528
}
521529

522530
public async findWorkspacesForPurging(

0 commit comments

Comments
 (0)