MDK Logo

Tear down MDK services

Stop Kernel, Gateway, and Workers cleanly

Overview

MDK registers graceful shutdown handlers automatically when you start services with getKernel(), a Worker boot function, or startGateway(). For most deployments, SIGINT (Ctrl+C) triggers a clean teardown with no extra code. This guide covers the three situations where you need to think about teardown explicitly:

Prerequisites

Automatic teardown with getKernel()

getKernel() registers SIGINT/SIGTERM handlers internally. 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')
const { startWhatsminerWorker } = require('@tetherto/mdk-worker-whatsminer')

const kernel = await getKernel()

const { runtime, stop } = await startWhatsminerWorker({ workerId: 'whatsminer-rack-1', model: 'm56s', storeDir: './data/whatsminer' })
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 — never receive SIGINT. 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')

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')

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

See onShutdown API reference.

What just happened

  1. Automatic chain: getKernel() 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