Many times, we need to run an arbitrary piece of code based on some schedule. The schedule can be a fixed time, a recurring interval or after a specific timeout. In this post, we will look at how to setup NestJS Task Scheduling using the NestJS Scheduler package.

In the linux world, this use-case is handled by cron packages available at OS Level. However, NestJS provides the @nestjs/schedule package. Basically, this package makes it very easy to setup cron-like jobs in a declarative manner.

Let’s dig deeper into the use of this package.

1 – Installation of NestJS Scheduler Package

To use the package, we have to first install it. Execute the below commands to perform the installation of these packages in your project.

$ npm install --save @nestjs/schedule
$ npm install --save-dev @types/cron

Once the installation is successful, we need to activate NestJS Task Scheduling. To activate, we we have to import the ScheduleModule into the AppModule and run the forRoot() static method.

See below example:

import { Module} from '@nestjs/common';
import { ScheduleModule } from '@nestjs/schedule';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [ScheduleModule.forRoot()],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

The forRoot() method call basically initializes the NestJS Scheduler. It also registers any declarative cron jobs, timeouts and intervals existing within our application context.

2 – Declaring a Cron Job

A cron job schedules an arbitrary method to run automatically. A typical cron job can run once at specified date/time. It can also run a specified instance within an interval. For example, once a day, once every hour or even every second.

We can declare a cron job by using the @Cron() decorator on the method-level in our service class. See below example:

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

@Injectable()
export class AppService {

  constructor(private schedulerRegistry: SchedulerRegistry){}

  @Cron('* * * * * *')
  triggerCronJob() {
    console.log("Calling the method every second");
  }
}

In the above example, the triggerCronJob() method will run every second. Basically, the @Cron() decorator supports all standard cron patterns such as asterisks (*), ranges (1-3), steps (*/2).

In case you want to know more about services, you can read this detailed post about NestJS Services.

The below key pattern explains how each position in the cron pattern does something.

* * * * * *
| | | | | |
| | | | | day of week
| | | | month
| | | day of month
| | hour
| minute
second (optional)

The @nestjs/schedule package also provides convenience enums with commonly used cron patterns. Below is a simple example for the same.

 @Cron(CronExpression.EVERY_5_SECONDS)
 triggerCronJobFiveSeconds() {
    console.log("Calling the method every 5 seconds");
 }

In the above snippet, the method will be called every 5 seconds.

We can also supply a Javascript Date object to the @Cron() decorator. This makes the job execute once at the specified date.

3 – Cron Decorator Additional Options

We can also supply some additional options while setting up the @Cron() decorator.

  • Name – This property is useful to access a cron job and alter its properties.
  • Timezone – Specify the timezone for the execution. If the timezone is invalid, an error will be thrown. You can find the valid timezone from the MomentJS website.
  • UTC Offset – This allows us to specify offset for our timezone.

See below example of using some of these properties.

@Cron('4 * * * * *', {
    name: 'messaging',
    timeZone: 'America/New_York'
})
triggerMessage(){
    console.log("Triggering Message Sending");
}

Here, we are basically using name and timeZone properties.

4 – NestJS Task Scheduling using Intervals

Cron is not the only way to schedule tasks in NestJS. We can also use Intervals and Timeouts.

Let us look at intervals first.

To declare a method to be run at specific interval, we can use the @Interval() decorator. See below example.

@Interval(2000)
triggerMethodBasedOnInterval(){
   console.log("Triggering the method after interval of 2 seconds");
}

Here, 2000 is the intervals in milliseconds. Basically, 2 seconds in this case.

info

INFO

Behind the scenes, this mechanism uses the Javascript setInterval() function.

We can also declare a named interval as below:

@Interval('messaging', 3500)
triggerMethodBasedOnNamedInterval() {
   console.log("Triggering the method after 3.5 seconds based on named interval");
}

In the above snippet, we can reference the interval using the name messaging. It will run after every 3.5 seconds.

5 – NestJS Task Scheduling using Timeouts

Many times, we need to perform an activity once. We can do so easily by using timeouts.

In order to use timeouts, we need to simply use the @Timeout() decorator. See below example:

@Timeout(3000)
handleTimeout() {
    console.log("Calling method once after timeout of 3 seconds");
}

The above piece of code will run 3000 milliseconds (or 3 seconds) after application startup.

Just like with Intervals, we can also declare named timeouts as below:

@Timeout('messaging', 3500)
handleNamedTimeout() {
    console.log("Calling method after 3.5 seconds based on named timeout.")
}

Conclusion

With this we have successfully looked at NestJS Task Scheduling using NestJS Scheduler. As we can see, NestJS provides various options to us in term of scheduling tasks. We can use cron, interval or timeout depending on our use-case.

We will be also looking in NestJS Dynamic Scheduling API in the next post.

If you have any comments or queries about this post, feel free to mention in the comments section below.


Saurabh Dashora

Saurabh is a Software Architect with over 12 years of experience. He has worked on large-scale distributed systems across various domains and organizations. He is also a passionate Technical Writer and loves sharing knowledge in the community.

0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *