tursodatabase / tursodatabase/libsql
Add Graceful Shutdown example to fix Nodemon hanging on restarts (EADDRINUSE)
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 17.2k
- Forks
- 531
- Avg merge
- 1h 12m
- Merged PRs (30d)
- 1
Description
Hello! I am a beginner using Turso with Express and Nodemon, and I recently ran into a very frustrating issue that took me a while to figure out.
I'm opening this issue as a documentation request because I think adding a small note about this could save other developers a lot of time!
The Problem I Faced 🐛
Whenever I saved a file, nodemon would attempt to restart my Express server, but it would fail or my new routes wouldn't show up. I was getting errors like:
Cannot GET /my-new-route(the server was stuck on the old code)EADDRINUSE: address already in use :::3000
It turns out that @libsql/client holds an active, persistent socket connection. When nodemon sends the restart signal (SIGUSR2), Node.js refuses to exit because the database connection is still keeping the event loop alive. This leaves the old server running as a "zombie" process holding port 3000.
The Solution 🛠️
I finally figured out that I needed to explicitly call tursoClient.close() inside a graceful shutdown handler so nodemon could clean up and restart properly.
Since this is such a common trap when setting up local development, could we add a small snippet about 'Graceful Shutdowns' to the official documentation?
Here is the solution code that worked perfectly for me, which might be helpful to add to the docs:
import express from "express";
import { createClient } from "@libsql/client";
const app = express();
const PORT = process.env.PORT || 3000;
export const tursoClient = createClient({
url: process.env.TURSO_DATABASE_URL!,
authToken: process.env.TURSO_AUTH_TOKEN!,
});
const server = app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
// Graceful shutdown — close turso connection so nodemon can restart cleanly
const shutdown = async () => {
console.log("Shutting down gracefully...");
tursoClient.close();
server.close(() => {
process.exit(0);
});
};
// Handle Ctrl+C
process.on("SIGINT", shutdown);
// Handle Docker/System shutdown
process.on("SIGTERM", shutdown);
// Handle Nodemon restarts
process.once("SIGUSR2", async () => {
await shutdown();
});
Thank you for the amazing database!
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No target file or test is named; begin by locating the official Express/Turso setup documentation. Add the supplied graceful-shutdown example and verify that it explains handling SIGINT, SIGTERM, and SIGUSR2 and closing the @libsql/client connection so Nodemon restarts without EADDRINUSE.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- express, node.js, typescript
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 65/100