perf(convex): bound unbounded owner-wide collects on hot paths
This commit is contained in:
@@ -234,6 +234,11 @@ const normalizeWorkspacePaths = (values: string[] | undefined, max: number) =>
|
||||
.filter((value, index, all) => all.indexOf(value) === index)
|
||||
.slice(0, max);
|
||||
|
||||
// Owner-wide scans for old-workspace cleanup are bounded to this many rows so
|
||||
// the query cost cannot grow without limit. The count is therefore reported as
|
||||
// "up to N"; delete is per-call bounded and re-runnable to drain the rest.
|
||||
const OLD_WORKSPACE_SCAN_LIMIT = 500;
|
||||
|
||||
const isDeletableWorkspace = (job: Doc<'agentJobs'>) =>
|
||||
['failed', 'cancelled', 'timed_out'].includes(job.status) ||
|
||||
['stopped', 'expired', 'failed'].includes(job.workspaceStatus ?? '');
|
||||
@@ -1069,7 +1074,7 @@ export const countOldWorkspaces = query({
|
||||
const jobs = await ctx.db
|
||||
.query('agentJobs')
|
||||
.withIndex('by_owner', (q) => q.eq('ownerId', ownerId))
|
||||
.collect();
|
||||
.take(OLD_WORKSPACE_SCAN_LIMIT);
|
||||
return jobs.filter(
|
||||
(job) => isDeletableWorkspace(job) && job.updatedAt <= cutoff,
|
||||
).length;
|
||||
@@ -1091,7 +1096,7 @@ export const deleteOldWorkspaces = mutation({
|
||||
const jobs = await ctx.db
|
||||
.query('agentJobs')
|
||||
.withIndex('by_owner', (q) => q.eq('ownerId', ownerId))
|
||||
.collect();
|
||||
.take(OLD_WORKSPACE_SCAN_LIMIT);
|
||||
const deletable = jobs
|
||||
.filter((job) => isDeletableWorkspace(job) && job.updatedAt <= cutoff)
|
||||
.sort((a, b) => a.updatedAt - b.updatedAt)
|
||||
|
||||
@@ -23,14 +23,26 @@ export const listForSpoon = query({
|
||||
.order('desc')
|
||||
.take(limit ?? 100);
|
||||
}
|
||||
const commits = await ctx.db
|
||||
.query('spoonCommits')
|
||||
.withIndex('by_owner', (q) => q.eq('ownerId', ownerId))
|
||||
.order('desc')
|
||||
.collect();
|
||||
return commits
|
||||
.filter((commit) => commit.spoonId === spoonId)
|
||||
.slice(0, limit ?? 100);
|
||||
const take = limit ?? 100;
|
||||
const [upstream, fork] = await Promise.all([
|
||||
ctx.db
|
||||
.query('spoonCommits')
|
||||
.withIndex('by_spoon_side', (q) =>
|
||||
q.eq('spoonId', spoonId).eq('side', 'upstream'),
|
||||
)
|
||||
.order('desc')
|
||||
.take(take),
|
||||
ctx.db
|
||||
.query('spoonCommits')
|
||||
.withIndex('by_spoon_side', (q) =>
|
||||
q.eq('spoonId', spoonId).eq('side', 'fork'),
|
||||
)
|
||||
.order('desc')
|
||||
.take(take),
|
||||
]);
|
||||
return [...upstream, ...fork]
|
||||
.sort((a, b) => (b.committedAt ?? 0) - (a.committedAt ?? 0))
|
||||
.slice(0, take);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user