perf: coalesce batch progress refreshes

This commit is contained in:
hectorzhao
2026-08-21 11:07:20 +08:00
parent 3c6f1beed1
commit 90345fba22
6 changed files with 53 additions and 0 deletions
@@ -24,6 +24,8 @@ export class SendGatewaySubmitService {
private sendQueue?: Queue<SendJob, unknown, 'send-message'>;
private gatewayQueue?: Queue;
private worker?: Worker<SendJob>;
private readonly taskProgressRefreshes = new Map<string, Promise<void>>();
private readonly dirtyTaskProgressRefreshes = new Set<string>();
constructor(
private readonly prisma: PrismaService,
@@ -449,6 +451,29 @@ async waitForChannelRateLimit(channelId: string, tps: number) {
}
async refreshTaskProgress(batchTaskId: string) {
const running = this.taskProgressRefreshes.get(batchTaskId);
if (running) {
// A state transition committed after the running aggregate may not be visible
// to its snapshot. Mark one trailing pass instead of issuing another identical
// GROUP BY concurrently for every message/result/receipt callback.
this.dirtyTaskProgressRefreshes.add(batchTaskId);
return running;
}
const refresh = this.refreshTaskProgressUntilClean(batchTaskId);
this.taskProgressRefreshes.set(batchTaskId, refresh);
try {
await refresh;
} finally {
if (this.taskProgressRefreshes.get(batchTaskId) === refresh) {
this.taskProgressRefreshes.delete(batchTaskId);
}
this.dirtyTaskProgressRefreshes.delete(batchTaskId);
}
}
private async refreshTaskProgressUntilClean(batchTaskId: string) {
do {
this.dirtyTaskProgressRefreshes.delete(batchTaskId);
const groups = await this.prisma.smsMessageRecord.groupBy({
by: ['status'],
where: { batchTaskId },
@@ -468,6 +493,7 @@ async refreshTaskProgress(batchTaskId: string) {
where: { id: batchTaskId },
data: { progressTotal, submittedTotal, successTotal, failedTotal, unknownTotal, timeoutTotal, status },
});
} while (this.dirtyTaskProgressRefreshes.has(batchTaskId));
}
getSendQueue(): Queue<SendJob, unknown, 'send-message'> {