dánwòdánwò

Real stacks

Processes

danwo stops everything it starts, when a run passes, fails, is interrupted or is killed. Here's how, and what your app should do.

A run starts browsers, workers, your apps and their children. When it ends, nothing it started is left running, whether it passed, failed, was interrupted with Ctrl-C or was killed outright.

What danwo cleans up

Started by danwoStopped when
your apps and everything they spawnthe worker ends
test workersthe run ends, or their parent goes away
browsers and their contextseach test ends
emulators and the proxythe worker ends

How an app is stopped

Each app's command runs as the leader of its own process group. A dev command often starts the real server as its child, and stopping the group stops both:

  1. the group gets SIGTERM;
  2. five seconds later, anything still running gets SIGKILL.

The same happens on Ctrl-C, SIGTERM or SIGHUP. If the worker itself is killed, a small guardian process notices and ends what the worker owned.

Windows has no process groups, so there danwo ends the app's whole process tree with taskkill /T /F. There is no guardian on Windows: a worker killed outright can leave its app running.

Have your app exit on SIGTERM: close its server and database pool, then exit. It will stop in well under five seconds.

Start your own processes the same way

An environment that starts a process itself, such as a search server or a mock service, should use spawnOwned. It takes the same arguments as Node's spawn and gives the child a stop():

search.ts
import { spawnOwned } from "@danwo/sdk"

export async function startSearch(): Promise<() => Promise<void>> {
  const search = spawnOwned(
    "typesense-server",
    ["--data-dir", "/tmp/search", "--api-key", "test"],
    {
      stdio: "inherit",
    },
  )

  return async () => {
    await search.stop()
  }
}

The child gets the same treatment as your apps: its own group, SIGTERM then SIGKILL, and the guardian if the worker dies.

Next

On this page

Run it on every pull request

A GitHub check and one comment per pull request, with the flight records attached.

Set up CI