node.jstypescriptcronnestjsscheduled-tasks

How can I ensure a cron task is executed only once in NestJS?


I'm using NestJS. I have a cron task that needs to run every 10 seconds. However, I need to ensure that the second task doesn't start if the first task is still running. In other words, the task should only be executed once at a specific moment in time. Additionally, if the task takes too long to complete, I would like to forcefully terminate its execution.

I couldn't find such a function in the @nestjs/schedule documentation. Perhaps someone already has a ready solution in the form of a decorator or in another form. I would appreciate it if you could share it.

import { Injectable } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';

@Injectable()
export class SchedulingService {
  @Cron('*/10 * * * * *', {name: 'schedulerTest'})
  async schedulerTest() {
    await this.testService.testFunc();
  }
}

How can I ensure a cron task is executed only once in NestJS?


Solution

  • The only way to do this without race conditions is with Locks. When you scale out nodes, you will also have this problem

    You can for example use Redis Locks

    When the task runs it will try to acquire a lock; if it can't it will assume another process is doing it already. When it can acquire the lock, it will simply execute and release the lock after.

    The other solutions in this thread all have the potential for race conditions and don't work when you have multiple nodes.