I have the following NgrokService
here:
@Injectable()
export class NgrokService
implements OnApplicationBootstrap, OnApplicationShutdown
{
port: string
ngrokToken: string
ngrok: typeof import('ngrok') | null = null
constructor(private readonly configService: ConfigService) {
this.port = this.configService.get('API_PORT') ?? '3001'
this.ngrokToken = this.configService.getOrThrow('NGROK_TOKEN')
if (process.env.NODE_ENV === 'development') this.ngrok = require('ngrok')
}
async onApplicationBootstrap() {
if (process.env.NODE_ENV !== 'development') {
return
}
this.tunnelUrl = await this.ngrok!.connect({
addr: `https://localhost:${this.port}`,
subdomain: '<my_subdomain>',
region: 'us',
authtoken: this.ngrokToken,
})
}
async onApplicationShutdown() {
if (process.env.NODE_ENV !== 'development') {
return
}
this.ngrok!.disconnect()
}
}
I'm using it here:
@Module({
imports: [],
controllers: [HealthController],
providers: [HealthService, AwsService, NgrokService],
})
export class HealthModule {}
and also here:
@Module({
imports: [
...
],
controllers: [...],
providers: [
...
NgrokService
],
})
export class AppModule {}
For some reason though, the onApplicationBootstrap
hook gets called twice. After digging, I was only able to solve it by wrapping the service in a module and creating a global lock variable that checks if the connection was already made.
I just want to understand why this is happening. Why is Nestjs instantiating the service twice? Even wrapped in a module, the service gets instantiated twice.
providers are singleton by default per module
so if you have NgrokService
registered (ie, in the providers
array) in multiple modules, you'll get multiple instances.