18

I'm looking for a way to trigger application shutdown from a service in Nest.js that will still call hooks.

I have a case when I'm handling a message in a service and in some scenario this should shutdown the application. I used to throw unhandled exceptions but when I do this Nest.js doesn't call hooks like onModuleDestroy or even shutdown hooks like onApplicationShutdown which are required in my case.

calling .close() from INestApplication works as expected but how do I inject it into my service? Or maybe there is some other pattern I could use to achieve what I'm trying to do?

Thank you very much for all the help.

Kim Kern
  • 54,283
  • 17
  • 197
  • 195
superrafal
  • 516
  • 1
  • 3
  • 10

1 Answers1

27

You cannot inject the application. Instead, you can emit a shutdown event from your service, let the application subscribe to it and then trigger the actual shutdown in your main.ts:

Service

export class ShutdownService implements OnModuleDestroy {
  // Create an rxjs Subject that your application can subscribe to
  private shutdownListener$: Subject<void> = new Subject();

  // Your hook will be executed
  onModuleDestroy() {
    console.log('Executing OnDestroy Hook');
  }

  // Subscribe to the shutdown in your main.ts
  subscribeToShutdown(shutdownFn: () => void): void {
    this.shutdownListener$.subscribe(() => shutdownFn());
  }

  // Emit the shutdown event
  shutdown() {
    this.shutdownListener$.next();
  }
}

main.ts

// Subscribe to your service's shutdown event, run app.close() when emitted
app.get(ShutdownService).subscribeToShutdown(() => app.close());

See a running example here:

Edit Nest shutdown from service

Kim Kern
  • 54,283
  • 17
  • 197
  • 195
  • 2
    It seems to get the job done, however it doesn't work nicely with @nestjs/typeorm which i'm using. I will try my luck with @nestjs/terminus package. – superrafal Jul 30 '19 at 19:25