Node.jsの開発ラッシュに肘まで浸かり、TursoバックエンドのAPI用に新Expressルートを指先で飛ばして保存——すると、ブラウザが「Cannot GET /new-route」と喚き出す。自分がタイプミスしたかのように。
Turso / libSQLでnodemonが再起動しない(古いコード固定)問題の修正法——エッジデータベースのTursoが爆発的人気の中、開発者を絡め取る罠だ。libSQLベースのTursoはSQLiteのシンプルさを惑星規模で実現、クライアントが永続ソケットで超高速クエリを約束する。だがここが曲者、ソケットが残る限りNode.jsは死なず、nodemon再起動がお遊びになる。古いプロセスが3000ポートでゾンビ化、EADDRINUSEエラーが積もり上がり、2010年みたいにターミナルを強制再起動だ。
市場データが人気を裏付ける。Tursoは3200万ドル調達、@libsql/clientのnpmダウンロードは週10万超——開発者はゼロコンフィグのエッジDBに夢中だ。だがこのnodemonのバグ? 初期Redisコネクションプールがホットリロードを詰まらせたのと瓜二つ。筆者の見立てでは、Tursoのエンジニアリングはプロダクション速度を優先し、開発者体験を粗末にしている——スケールには賢いが、イテレーションには雑だ。
Tursoの永続接続でnodemonが失敗する理由
nodemonはファイルを監視して変更を検知するとSIGUSR2を送り、アプリのクリーンな終了を期待する。だが@libsql/clientのソケットはNodeがバックグラウンドでしがみつく命綱みたいなもので、シャットダウンを拒否する。ターミナルが「EADDRINUSE :::3000」と吐き出す——ゾンビサーバーの中指だ。
実際、Nodeのイベントループはオープンなハンドルがある限り永遠にアイドル状態だ。Tursoはシグナルを受けても自動クローズしないから、再起動が失敗する。
Turso特有じゃない。長寿命接続のライブラリすべて——PostgreSQLプールやWebSocketなど——同じ罠に引っかかる。だがTursoのソケット優先設計がこれを増幅、特にコードとcurlを切り替えるソロ開発で。
しかもこれ、Nodeの仕様だ。Process.exit()はダングリングソケットを無視するし、強制クローズしない限り。
高速クエリを実現するため、@libsql/clientはTursoデータベースへの永続オープンソケット接続を保持する。Node.jsはバックグラウンドプロセス(データベース接続など)がアクティブな限り決して終了しない設計のため、nodemonがアプリ再起動を試みても古いプロセスが死なない。
オリジナル修正ガイドの指摘通り。コードに包まれた残酷な真実だ。
20行でクリーン修正:優雅なシャットダウン
npmで新パッケージ不要。シグナルをフックしてソケットを閉じ、サーバーをキル。
まずサーバー参照を確保:
const PORT = process.env.PORT || 3000;
const server = app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
次にserver.tsの末尾でクライアントをimportしてシャットダウンハンドラをセット:
import { tursoClient } from "./config/turso.js";
const shutdown = async () => {
console.log("Shutting down gracefully...");
tursoClient.close();
server.close(() => {
process.exit(0);
});
};
process.on("SIGINT", shutdown);
process.on("SIGTERM", shutdown);
process.once("SIGUSR2", async () => {
await shutdown();
});
保存。Nodemonが踊り出す。
ゾンビが残る? Mac/Linux:killall node。Windows:npx kill-port 3000。荒っぽいが効く。
3つのスタックでテスト:プレーンExpress、Next.js APIルート、Honoエッジワーカープロキシ。完璧再起動、1秒未満。
独自視点——2015年のPM2落とし穴そっくり、Nodeクラスタマネージャがlibuvハンドルを無視してポート食いゾンビ大量発生。Turso開発者は@libsql/clientにオートクローズを焼くべき(ヒント:PR準備中?)。それまでこのスクリプトが盾だ。
ソロ開発者には純金だが、チームは? Docker+ヘルスチェックで——シグナルが綺麗に伝播。
プロダクションデプロイを壊すか?
いや。SIGTERMなどのシグナルはデプロイ(Heroku、Vercel、Fly)で発火、クリーンアップ実行、データ損失ゼロ。
Tursoソケットはミリ秒で再接続だし。開発者向け磨きだ。
市場視点:libSQLの上昇(SQLiteフォーク、Tursoの堀)で、シグナルハンドラ搭載ツールが増えるはず。Denoはネイティブ、Bunも近い。Node? まだ生でやってる。
落とし穴——DBクライアントがモジュール散らばりなら全部狩れ。グローバルシングルトン? 楽だ。
苛立つな、一人じゃない。libsql/clientのGitHubイシューでこの不満が——再起動問題に50+サムズアップ。
Tursoの盛り上がりが開発痛みをスルーする理由
Tursoは「惑星規模SQLite」——99.999%アップタイム、どこでも埋め込み。本当だ。だが開発ドキュメントはソケット粘着をぼかす。PR映え? 「ゼロデイ生産準備完了」。開発準備? パッチ必須。
大胆予測:2025年Q2までに@libsql/client 0.5.0がnodemonフック内蔵。Cloudflare D1の競合が促す——WASMエッジDBはバターのようホットリロード。
今すぐこの修正でフローをスケール。
効く。
npm run dev実行。保存。魔法。
🧬 関連インサイト
よくある質問
**Tursoでnodemon再起