Nest Js dynamic cron jobs
Nest Js has a great component which implement cron jobs. the greatest feature we can make jobs dynamic, it is very helpful in our project
I want to share knowledge that how implement this feature in our project
let’s assume we have many task and every task should run different a specific time, our task is collection all jobs and register to nest js schedule component
for install component run it in terminal
$ npm install --save @nestjs/schedule
First of all, we need to create Abstract class which all cron service get inherent from it
export abstract class AbstractScheduler {
public abstract name: string;
public abstract timeExpression: string;
public abstract run();
}
there are two property and method, name is name of the cron job. timeExpression is which time period cron should be call run function
let’s create first cron job
@Injectable()
export class DailyReportScheduler extends AbstractScheduler {
public name: string = 'daily_report';
public timeExpression: string = CronExpression.EVERY_DAY_AT_8PM;
public run() {
// calculate and send daily report
}
}
and second cron job
@Injectable()
export class MonthlyReportScheduler extends AbstractScheduler {
public name: string = 'monthly_report';
public timeExpression: string = CronExpression.EVERY_1ST_DAY_OF_MONTH_AT_MIDNIGHT;
public run() {
// calculate and send monthly report
}
}
add following code to your module for collecting cron jobs to one service provider
@Module({
providers: [
MonthlyReportScheduler,DailyReportScheduler
{
provide: 'SCHEDULES',
useFactory: (...schedules) => {
return schedules;
},
inject: [
MonthlyReportScheduler, DailyReportScheduler
],
},
],
exports: [],
})
export class AppModule {
}
also register Scheduler classes as provider. We create provider with tag SCHEDULES which we can inject this provider with alias inside of constructor
@Injectable()
export class TaskScheduleRegistery implements OnApplicationBootstrap {
private readonly logger = new Logger(TaskScheduleService.name);
onApplicationBootstrap(): any {
this.logger.log('Task scheduler has been booting');
this.registerCronJobs();
}
constructor(
@Inject('SCHEDULES')
private readonly schedules: AbstractScheduler[],
private readonly scheduleRegistry: SchedulerRegistry,
) {
}
registerCronJobs() {
for (const job of this.schedules) {
this.logger.log(`${job.name} cron has added with expression ${job.timeExpression}`);
this.scheduleRegistry.addCronJob(job.name, new CronJob(job.timeExpression, () => {
this.logger.log(`${job.name} cron is starting with expression ${job.timeExpression}`);
job.run();
}, () => {
this.logger.log(`${job.name} cron has completed with expression ${job.timeExpression}`);
}, true));
}
}
}
this service has implemented OnApplicationBootstrap interface, while nest js application bootstrapping then our jobs being register to the nestjs schedule component
if you want to know more go to nest js documentation