MDK Logo

Tear down MDK services

Stop Kernel, Gateway, and Workers cleanly

Overview

As a library, MDK leaves your process's signals alone: getKernel() and startGateway() install SIGINT/SIGTERM handlers only when you pass handleSignals: true, which a standalone process does so that Ctrl+C triggers a clean teardown with no extra code. This guide covers the three ways to tear down:

Prerequisites

Automatic teardown with getKernel()

getKernel({ handleSignals: true }) registers SIGINT/SIGTERM handlers that drain the cleanup chain, stop the Kernel and exit the process. Without the option no handler is installed. A Gateway started with opts.kernel is chained into the cleanup sequence automatically. Workers are not auto-chained: a Worker's boot function has no opts.kernel, so push its stop() onto kernel._cleanup yourself if you want Kernel shutdown to cascade to it:

const { getKernel, startGateway } = require('@tetherto/mdk-core')
const { startAvalonWorker } = require('@tetherto/mdk-worker-avalon')

const kernel = await getKernel({ handleSignals: true })

const { runtime, stop } = await startAvalonWorker({ workerId: 'avalon-rack-1', model: 'a1346', storeDir: './data/avalon' })
await kernel.registerWorker(runtime.getPublicKey())
kernel._cleanup.push(stop) // cascade Worker shutdown from Kernel

await startGateway({ kernel, port: 3000 })

// Press Ctrl+C: MDK stops Gateway, then the Worker, then Kernel.

See getKernel API reference and the Workers discovery model for the same-process lifecycle rules.

Explicit teardown in tests or scripted runs

Short-lived processes — integration tests, one-shot scripts — and embedders that own their signals (the default) call shutdown(kernel) directly to drain the full cleanup chain. Pass the kernel object returned by getKernel(); passing a server object stops only the Gateway.

const { getKernel, startGateway, shutdown } = require('@tetherto/mdk-core')

const kernel = await getKernel()
await startGateway({ kernel })

// … run assertions or perform work …

await shutdown(kernel) // stops Gateway (chained), then stops Kernel

See shutdown API reference.

Custom signal handling with onShutdown

Use onShutdown when you need to close resources outside an MDK boot object — for example, a database connection or a log buffer.

const { onShutdown } = require('@tetherto/mdk-core')

onShutdown(async () => {
  await db.close()
  await logger.flush()
}, { forceMs: 5000 })

See onShutdown API reference.

What just happened

  1. Automatic chain: getKernel({ handleSignals: true }) and startGateway({ kernel }) wire themselves into kernel._cleanup so a single signal stops Kernel and Gateway in order; push a Worker's stop() onto kernel._cleanup yourself to fold it into the same chain.
  2. Explicit drain: shutdown(kernel) gives you the same ordered teardown on demand, without a signal.
  3. Custom hooks: onShutdown(fn) lets you attach cleanup logic outside the MDK object hierarchy.

Next steps

On this page