Skip to main content

Module exit

Module exit 

Source
Expand description

Durable-mode auto-flush-on-exit.

A durable Db stages id-index updates in an in-memory WAL (write_buf) and only makes them durable in flush_all() — normally driven by the manifest ticker or by Drop. But Drop “only fires once every owning handle is gone”, and a ticker thread (or a server that blocks forever in serve()) holds an Arc<Db> for the whole process lifetime — so on a hard exit (Ctrl+C, SIGTERM from an orchestrator, kill) Drop NEVER runs and the writes staged since the last tick are lost. That is the gap this module closes.

Db::install_exit_flush registers a durable database to be flushed when the process receives SIGINT or SIGTERM. It flushes exactly once, on the way out — NOT on every put — so the hot write path stays hot.

§Design

  • Opt-in. A library that unilaterally seizes signal handlers would trample a host application’s own shutdown logic, so the core never installs this implicitly. The napi (nedb-node) and pyo3 (nedb-py) open() paths call it for durable databases — so Node and Python embedders get flush-on-exit for free — and Rust applications call it explicitly. nedbd keeps its own tokio graceful-shutdown handler and does not use this.

  • Async-signal-safe. The installed handler does exactly one thing: a non-blocking write(2) of the signal number to a self-pipe (write is on the POSIX async-signal-safe list). A dedicated reader thread blocks on the read end; when woken it runs flush_all() on every registered database from a normal thread context (locks, allocation and file I/O are all safe there), restores the signal’s default disposition, and re-raises it so the process terminates with the correct 128 + signum status.

  • Idempotent. The handler and reader thread are installed once per process; each subsequent call just registers another database. In-memory (:memory:) databases are ignored — there is nothing to flush.

  • Weak references. The registry holds Weak<Db>, so a registered database that is otherwise dropped is not kept alive (no leak) and is pruned on the next flush pass.