#Dynamic module import based on ConfigService instance getter

9 messages · Page 1 of 1 (latest)

candid heath
#

Hey there, I'm trying to use the configService instance in a dynamic module, but I'm not sure how to do it. Here's my code:

@Module({})
export class CronModule {
  static register(): DynamicModule {
    const imports = [
      CqrsModule,
    ];

    if (configService.nestCronEnabled) {
      imports.push(DevCronModule);
    }
    return {
      imports,
      module: CronModule,
      controllers: [CronController],
      providers: [CronKeyStrategy, InvoiceRepository],
    };
  }
}

I want to add CronModule based on ConfigService getter, how can i get the configService instance here ? Thanks !

If i create a new instance it look to work but I'm afraid of side effects :

    const configService = new ConfigService();
    if (configService.nestCronEnabled) {
      imports.push(DevCronModule);
    }
spring peak
#

i was also searching for a solution for this exact problem
scoured google and many guides and that got me nowhere
in the end i took a step back and solved the issue elsewhere

instead of dynamically pushing the dev cron module to the imports list
try solving the problem inside the dev crone module itself.

in my case i wanted to not connect to an AWS message queue unless sepcifically specified
so i ended up adding an if(configserice.get(...) around the part where i start the listener instead

in your specific case:
there should probabaly be an area of code where you "start" the cron job or initialize the service inside the cron module itself
find it and wrap that in a config check instead

candid heath
#

Hi @spring peak , thanks for your feedback, yes I thought about it but the cron will still run and do nothing, which I guess is not great for performance. Re instantiate the configService is maybe the best option

spring peak
candid heath
#

Here is my cron service :

import { PublishEventsCommand } from 'src/event/domain/use-cases/publish-events/commands/publish-events.command';
import { VerifyEventCommands } from 'src/event/domain/use-cases/verify-event/commands/verify-event.commands';
import { Injectable } from '@nestjs/common';
import { CommandBus } from '@nestjs/cqrs';
import { Interval } from '@nestjs/schedule';

const threeSecondsInMilliseconds = 3000;
const oneMinuteInMilliseconds = 60000;

@Injectable()
export class DevCronService {
  constructor(private readonly commandBus: CommandBus) {}

  @Interval(threeSecondsInMilliseconds)
  async publishEvent() {
    await this.commandBus.execute(new PublishEventsCommand());
  }

  @Interval(oneMinuteInMilliseconds)
  async verifyEvents() {
    await this.commandBus.execute(new VerifyEventCommands());
  }
}

One way might be to create a dynamic cron in the constructor of the service to start it based on the condition : https://docs.nestjs.com/techniques/task-scheduling#dynamic-schedule-module-api

spring peak
#

might not be relevant, but i found that you can inject schedulerRegistery
and from it, stop scheduled jobs

candid heath
#

Yes I've seen that too, I haven't tested it but it can be a solution. I was just wondering if in some cases the job could not start before it stops because it starts every 3 seconds

#

and it must not be executed in production

spring peak
#

it might be a solution
if you switch to the syntax of adding cron jobs through it, instead of via the @interval decorator
that'll give you the fine-grained control to also not add jobs