Skip to main content

Application

Ditsmod allows you to write applications using different architectural styles:

Ditsmod provides an API that allows adding support for the required architecture. Such packages are more than ordinary feature modules, since they also include an application class and an application initializer class, where the application configuration, the application build sequence, etc. are defined. As a rule, each of these packages has its own specifics regarding the metadata of their modules. In addition, if the application's web server has its own specifics of operation for different Runtimes (Node, Bun, Deno, etc.), Ditsmod allows taking this into account precisely at the stage of initializing the application class.

An instance of the application class is typically created in the main.ts file, and the application starts working from there. For example, an instance of a REST application class is created as follows:

src/main.ts
import { RestApplication } from '@ditsmod/rest';
import { AppModule } from './app/app.module.js';

const app = await RestApplication.create(AppModule);
app.server.listen(3000, '0.0.0.0');

Graceful Shutdown

Ditsmod supports graceful shutdown, allowing the application to close HTTP connections, stop accepting new requests, wait for active requests to finish, and run cleanup tasks in singleton services before exiting.

Enabling Shutdown Hooks

To enable graceful shutdown, call enableShutdownHooks() on the application instance. You can optionally pass an array of system signals (e.g., SIGTERM, SIGINT).

src/main.ts
import { RestApplication } from '@ditsmod/rest';
import { AppModule } from './app/app.module.js';

const app = await RestApplication.create(AppModule);
app.enableShutdownHooks();
app.server.listen(3000, '0.0.0.0');

By default, the following signals are listened to: ['SIGTERM', 'SIGINT', 'SIGHUP', 'SIGUSR2', 'SIGQUIT'].

Lifecycle Hooks

Services registered as singletons (e.g., providersPerApp or providersPerMod) can implement lifecycle hooks to perform cleanups:

  1. BeforeShutdown: Executed before the HTTP server begins to close. Ideal for notifying background tasks to stop.
  2. OnShutdown: Executed after the HTTP server is closed. Ideal for closing database pools, redis clients, etc.

Both hooks receive the triggered system signal as a parameter and can return void or Promise<void>.

src/app/my.service.ts
import { BeforeShutdown, OnShutdown, injectable } from '@ditsmod/core';

@injectable()
export class MyService implements BeforeShutdown, OnShutdown {
beforeShutdown(signal?: string) {
console.log(`Received ${signal}. Stopping background jobs...`);
}

async onShutdown(signal?: string) {
console.log(`Closing database connections...`);
await this.db.close();
}
}

Connection Draining (REST)

In @ditsmod/rest, when a shutdown signal is received:

  1. The server stops accepting new connections immediately (server.close()).
  2. All idle keep-alive connections are immediately closed.
  3. Active connections are allowed to finish their current requests.
  4. If active connections do not close within shutdownTimeout (default 15 seconds), they are forcefully closed.

You can configure shutdownTimeout (in milliseconds) via AppOptions in your root module:

import { AppOptions } from '@ditsmod/core';
import { RestModule } from '@ditsmod/rest';

@rootModule({
imports: [RestModule],
providersPerApp: [
{ token: AppOptions, useValue: { shutdownTimeout: 20000 } }
]
})
export class AppModule {}