jan*_*iks 5 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
}
}
Run Code Online (Sandbox Code Playgroud)
是否可以防止这些任务重叠并且一次只调用一个实例的任务?从技术上讲,我们可以跟踪一个lock变量,但这只会允许我们跳过一个实例(如果实例已经在运行)。理想情况下,我们可以调用 set 一个选项来允许基于任务结束时间的间隔,而不是固定间隔(也称为开始时间)。
这在 NestJS 中很容易完成,但您需要重构您的代码。
不要使用@Interval,而是使用 ,@Cron因为它有更多我们将在下一行中使用的选项。
让我们首先替换间隔装饰器:
@Interval(1000)
async handleCron() {
this.logger.debug(`start ${c}`);
await timeout(3000)
this.logger.debug(`end ${c}`);
c += 1
}
Run Code Online (Sandbox Code Playgroud)
变成:
@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
}
Run Code Online (Sandbox Code Playgroud)
我们在这里所做的是,我们使用了更具表现力的 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
}
Run Code Online (Sandbox Code Playgroud)
不要忘记将调度程序注册表服务注入到服务的构造函数中。
private schedulerRegistry: SchedulerRegistry,
Run Code Online (Sandbox Code Playgroud)
还有进口:
import { Cron, CronExpression, SchedulerRegistry } from '@nestjs/schedule'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3724 次 |
| 最近记录: |