Skip to content

Windows lifecycle mode for persistent reused clusters #28

Description

@m3ridian-zero

Summary

On Windows, embedded-postgres currently starts the postgres postmaster as a child of the caller's terminal session and registers an unconditional process-exit shutdown hook. That makes it difficult to run one persistent embedded cluster that is reused by several local processes.

This is a lifecycle/isolation issue rather than a Postgres data issue.

Environment

  • Package: embedded-postgres@17.10.0-beta.17
  • OS: Windows 11 x64
  • Runtime observed with: Bun 1.3.x / Node-compatible child_process
  • Postgres: package-provided Windows x64 binary

Observed behavior

  1. Start a persistent embedded cluster from a terminal.
  2. Reuse that cluster from another process.
  3. Press Ctrl+C in the terminal that started the cluster, or let a short-lived starter process exit.

Observed effects:

  • The postmaster/backends can receive the terminal Ctrl+C event, causing query cancellation and/or fast shutdown of the cluster.
  • The package-level async-exit-hook shutdown handler stops the cluster when the starter process exits, even when the caller wants a persistent shared cluster to outlive that process.
  • The current readiness check is tied to parsing stderr output from the child process. A detached/hidden-console launch mode needs connection-based readiness polling instead.

Expected behavior

There should be a supported lifecycle mode for persistent reused clusters where:

  • Ctrl+C in the starter terminal does not reach the Postgres postmaster/backends.
  • The cluster can intentionally outlive a short-lived process when persistent: true and the caller asks for detached/shared lifecycle behavior.
  • stop() still works explicitly.
  • Startup readiness is detected by connecting to Postgres instead of relying only on stderr log parsing.

Implementation direction that worked downstream

A downstream patch solved this by:

  • On Windows, launching the postmaster with CreateProcessW and CREATE_NO_WINDOW, tracking the returned postmaster PID for stop().
  • On POSIX, spawning detached so terminal SIGINT does not reach the postmaster.
  • Polling pg with SELECT 1 until startup/WAL recovery finishes.
  • Making implicit shutdown-on-parent-exit optional for the persistent shared-cluster use case.

I am happy to follow up with a PR if this direction fits the project's API. The key API question is whether this should be a new option such as shutdownOnExit?: boolean / detached?: boolean, or a broader lifecycle mode option.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions