如何正确实现调度器和Cron?

编程语言 2026-07-09

I在 NestJS框架中实现了一个调度器,获取所有记录(排除已处理的记录),应用业务逻辑,然后将输出保存到另一张表中。到目前为止,运行顺利,但在处理大约5,500条记录后就停止了,而未处理的记录超过10万条。

this.processLogic() 包含了全部的业务逻辑,并且还将 unprocessedTableisProcessed 字段更新为 true

我跳过的日期是在摄取阶段数据不完整的行(例如,某个用户还没有登出记录,或者在计划的摄取期间仍在工作)。我需要跳过这些行,以避免生成不正确的输出。

我预计每天会有成千上万次数据导入,并且不希望这个过程在生产环境中崩溃。

现在,我怀疑自己不小心在某处创建了无限循环,但还不能完全确定。

@Timeout(0)
  async processRecords() {
    const projectCodes = await this.codes.findMany();
    const now = new Date();
    const lilo =
      await this.unprocessedTable.findMany({
        where: {
          isProcessed: false,
        },
        include: {
          a: true,
          b: true,
          c: true,
        },
        orderBy: {
          d: 'desc',
        },
      });

    for (const record of lilo) {
      const GRACE_PERIOD = 5 * 60 * 60 * 1000; // +5 hours

      if (record.shiftDate && record.shiftFrom && record.shiftTo) {
        const shiftEnd = new Date(record.shiftDate);

        const hours = record.shiftTo.getUTCHours();
        const minutes = record.shiftTo.getUTCMinutes();
        const seconds = record.shiftTo.getUTCSeconds();

        shiftEnd.setUTCHours(hours, minutes, seconds, 0);

        if (record.shiftFrom > record.shiftTo) {
          shiftEnd.setDate(shiftEnd.getDate() + 1);
        }

        const processAfter = new Date(shiftEnd.getTime() + GRACE_PERIOD);

        if (now < processAfter) {
          console.log('Date to SKIP:', processAfter);
          continue;
        }

        if (!record.vcLastLogout || !record.proLastLogout) {
          continue;
        }
        console.log(`${record.recordId} timelog success!`);


        await this.processLogic(record, projectCodes);
      }
    }


    console.log('Cron executed');
  }

解决方案

你可以使用 @Timeout注解,在模块初始化后0 秒执行该函数一次

应使用实现Cron作业的 @nestjs/schedule库。

请阅读此文档 https://docs.nestjs.com/techniques/task-scheduling

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章