javascript - 是否可以防止计划任务在 NestJS 中重叠?

标签 javascript scheduled-tasks nestjs

目前,如果完成请求所需的时间大于间隔,长时间运行的任务将重叠(同一任务同时运行多个实例)。下面的示例 NestJS 服务

import { Injectable, Logger } from '@nestjs/common';
import { Interval } from '@nestjs/schedule';

function timeout(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

let c = 1

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  @Interval(1000)
  async handleCron() {
    this.logger.debug(`start ${c}`);
    await timeout(3000)
    this.logger.debug(`end ${c}`);
    c += 1
  }
}
是否可以防止这些任务重叠并且一次只调用一个实例的任务?从技术上讲,我们可以跟踪 lock变量,但这只会允许我们跳过一个实例,如果一个实例已经在运行。理想情况下,我们可以调用 set 一个选项来允许基于任务结束时间的间隔,而不是固定间隔(也称为开始时间)。

最佳答案

在 NestJS 中很容易完成,但您需要重构代码。
而不是使用 @Interval , 使用 @Cron因为它有更多我们将在下一行中使用的选项。
让我们首先替换间隔装饰器:

@Interval(1000)
  async handleCron() {
    this.logger.debug(`start ${c}`);
    await timeout(3000)
    this.logger.debug(`end ${c}`);
    c += 1
  }
变成:
@Cron(CronExpression.EVERY_SECOND, {
     name: 'cron_job_name_here',
   })
async handleCron() {
        this.logger.debug(`start ${c}`);
        await timeout(3000)
        this.logger.debug(`end ${c}`);
        c += 1
   }
我们在这里所做的是,我们使用了更具表现力的 cron 表达式,即使是非程序员也能理解这项工作将每秒运行一次。此外,我们命名了 cron 作业,所以现在我们可以通过调度程序的模块 API 来操作 cron 作业。
现在我们的 cron 作业有了名称,我们可以使用调度程序注册表轻松启动/停止它。所以你的功能变成:
@Cron(CronExpression.EVERY_SECOND, {
     name: 'cron_job_name_here',
   })
async handleCron() {
        const job = this.schedulerRegistry.getCronJob('cron_job_name_here');
        job.stop(); // pausing the cron job

        this.logger.debug(`start ${c}`);
        await timeout(3000)
        this.logger.debug(`end ${c}`);
        c += 1;

        job.start(); // restarting the cron job
   }
不要忘记将调度程序注册服务注入(inject)到服务的构造函数中。
private schedulerRegistry: SchedulerRegistry,
还有进口:
import { Cron, CronExpression, SchedulerRegistry } from '@nestjs/schedule'

关于javascript - 是否可以防止计划任务在 NestJS 中重叠?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66501485/

相关文章:

java - 如何将 CRON 任务设置为每组实例仅运行一次?

jestjs - 找不到 Nestjs 测试模块

javascript - 在 Canvas 上找到最理想的位置来书写文字

java - 为什么调度任务执行固定速率中的代码不起作用?

mysql - 在 Windows 上使用任务计划程序未完全执行批处理文件

typescript - NestJS 在 e2e 测试中模拟 JWT 身份验证

javascript - 针对实际数据库测试 NestJS 服务

javascript - 有没有纯函数式的方法来合并 JavaScript 中的对象?

javascript - 有没有办法不加载 jQuery?

javascript - jQuery 文件树 - 检测何时单击文件夹