nestjs dynamic task scheduling - context lost
Asked Answered
D

1

6

With declarative task scheduling in NestJS, context is preserved in the scheduled task, so the below code works fine.

@Injectable()
export class SchedulerService {
  private readonly log: Logger;

  constructor(
    @Inject(WINSTON_MODULE_PROVIDER) logger: Logger,
    private schedulerRegistry: SchedulerRegistry
  ) {
    this.log = logger.child({ context: 'scheduler service' });
  }

  @Cron('*/5 * * * * *')
  myScheduledTask(): void {
    this.log.info('test');
  }

However, when scheduling the same task dynamically, this.log is undefined in the scheduled function. How is this possible ?

@Injectable()
export class SchedulerService {
  private readonly log: Logger;

  constructor(
    @Inject(WINSTON_MODULE_PROVIDER) logger: Logger,
    private schedulerRegistry: SchedulerRegistry
  ) {
    this.log = logger.child({ context: 'scheduler service' });

    const userSyncJob = new CronJob('*/5 * * * * *', this.myScheduledTask);
    schedulerRegistry.addCronJob(syncJobName, userSyncJob);
    userSyncJob.start();
  }

  myScheduledTask(): void {
    this.log.info('test');
  }
}
24/7 08:12:09 [error] Nest : uncaughtException: Cannot read property 'info' of undefined
TypeError: Cannot read property 'info' of undefined
    at CronJob.syncUsers (C:\Users\lcartreul\Documents\projecten\rsa-user-management\src\otherservices\scheduler.service.ts:39:14)
    at CronJob.fireOnTick (C:\Users\lcartreul\Documents\projecten\rsa-user-management\node_modules\cron\lib\cron.js:562:23)
    at Timeout.callbackWrapper [as _onTimeout] (C:\Users\lcartreul\Documents\projecten\rsa-user-management\node_modules\cron\lib\cron.js:629:10)
    at listOnTimeout (internal/timers.js:549:17)
    at processTimers (internal/timers.js:492:7)
Debar answered 24/7, 2020 at 6:19 Comment(1)
Maybe this is not set correctly. Have you tried this.myScheduledTask.bind(this) instead of this.myScheduledTask?Carniola
R
6
const userSyncJob = new CronJob('*/5 * * * * *', this.myScheduledTask.bind(this));

or

const userSyncJob = new CronJob('*/5 * * * * *', () => this.myScheduledTask());

You're welcome

Roadrunner answered 24/7, 2020 at 8:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.