Skip to content

Add graceful shutdown (SIGTERM/SIGINT handlers) for clean Docker stop #58

Description

@pike00

Summary

The bridge has no signal handlers. When run under Docker, docker stop sends SIGTERM, which Deno ignores by default. After 10 seconds Docker escalates to SIGKILL, killing the process mid-operation. This can corrupt the CouchDB since checkpoint (stored in Deno localStorage), causing the bridge to re-replay or skip changes on restart.

Fix

Add SIGTERM/SIGINT handlers that call Hub.stop(), which awaits all peers' stop() methods (closing file watchers and flushing the localStorage checkpoint). The handler is idempotent via a shuttingDown guard.

Hub.ts — add stop() method

+async stop() {
+    await Promise.all(this.peers.map((p) => p.stop()));
+    this.peers = [];
+}

main.ts — add signal handlers

 const hub = new Hub(config);
 hub.start();
+
+let shuttingDown = false;
+async function shutdown(sig: string) {
+    if (shuttingDown) return;
+    shuttingDown = true;
+    console.log(\`LiveSync Bridge received ${sig}, shutting down...\`);
+    try {
+        await hub.stop();
+    } catch (ex) {
+        console.error(ex);
+    }
+    Deno.exit(0);
+}
+for (const sig of ["SIGTERM", "SIGINT"] as const) {
+    Deno.addSignalListener(sig, () => {
+        void shutdown(sig);
+    });
+}

Impact

Every Docker deployment benefits. Without this, docker stop is effectively a kill -9 after 10 seconds, risking checkpoint corruption on every restart.

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