chore(server): reschedule doc merging jobs (#11318)

This commit is contained in:
forehalo
2025-04-01 10:57:54 +00:00
parent d38458b733
commit 6276732efc
8 changed files with 90 additions and 50 deletions

View File

@@ -2,7 +2,8 @@ import { Injectable } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';
import { PrismaClient } from '@prisma/client';
import { JobQueue, metrics, OnJob } from '../../base';
import { JOB_SIGNAL, JobQueue, metrics, OnJob } from '../../base';
import { Models } from '../../models';
import { PgWorkspaceDocStorageAdapter } from '../doc';
declare global {
@@ -20,7 +21,8 @@ export class DocServiceCronJob {
constructor(
private readonly workspace: PgWorkspaceDocStorageAdapter,
private readonly prisma: PrismaClient,
private readonly job: JobQueue
private readonly job: JobQueue,
private readonly models: Models
) {}
@OnJob('doc.mergePendingDocUpdates')
@@ -29,30 +31,40 @@ export class DocServiceCronJob {
docId,
}: Jobs['doc.mergePendingDocUpdates']) {
await this.workspace.getDoc(workspaceId, docId);
const updatesLeft = await this.models.doc.getUpdateCount(
workspaceId,
docId
);
return updatesLeft > 100 ? JOB_SIGNAL.Repeat : JOB_SIGNAL.Done;
}
@Cron(CronExpression.EVERY_10_SECONDS)
@Cron(CronExpression.EVERY_30_SECONDS)
async schedule() {
const group = await this.prisma.update.groupBy({
by: ['workspaceId', 'id'],
_count: true,
});
const group = await this.models.doc.groupedUpdatesCount();
for (const update of group) {
if (update._count > 100) {
await this.job.add(
'doc.mergePendingDocUpdates',
{
workspaceId: update.workspaceId,
docId: update.id,
},
{
jobId: `doc:merge-pending-updates:${update.workspaceId}:${update.id}`,
priority: update._count,
delay: 0,
}
);
const jobId = `doc:merge-pending-updates:${update.workspaceId}:${update.id}`;
const job = await this.job.get(jobId, 'doc.mergePendingDocUpdates');
if (job && job.opts.priority !== 0 && update._count > 100) {
// reschedule long pending doc with highest priority, 0 is the highest priority
await this.job.remove(jobId, 'doc.mergePendingDocUpdates');
}
await this.job.add(
'doc.mergePendingDocUpdates',
{
workspaceId: update.workspaceId,
docId: update.id,
},
{
jobId: `doc:merge-pending-updates:${update.workspaceId}:${update.id}`,
priority: update._count > 100 ? 0 : 100,
delay: 0,
}
);
}
}

View File

@@ -105,6 +105,7 @@ export class PgWorkspaceDocStorageAdapter extends DocStorageAdapter {
// keep it simple to let all update merged in one job
jobId: `doc:merge-pending-updates:${workspaceId}:${docId}`,
delay: 30 * 1000 /* 30s */,
priority: 100,
}
);
turn++;

View File

@@ -101,7 +101,7 @@ export class MailJob {
...options,
});
return result === false ? JOB_SIGNAL.RETRY : undefined;
return result === false ? JOB_SIGNAL.Retry : undefined;
}
private async fetchWorkspaceProps(workspaceId: string) {