Turso/libSQLでnodemon再起動しないのを修正

保存の最中、新ルートが404の奈落に消える。Tursoの高速ソケットが密かにnodemon再起動を妨害しているのが原因だ。

Tursoでnodemonがゾンビ化するソケットの罠——開発者がスルーできない — theAIcatchup

Key Takeaways

  • Tursoの永続ソケットがNodeプロセスの終了を阻み、nodemon再起動をブロックする。
  • 20行シグナルハンドラーで修正:DB閉じ、サーバー閉じ、process.exit(0)。
  • ゾンビ残存?ポート手動キル、プロダクションデプロイ無影響。

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再起

Priya Sundaram
Written by

Hardware and infrastructure reporter. Tracks GPU wars, chip design, and the compute economy.

Worth sharing?

Get the best AI stories of the week in your inbox — no noise, no spam.

Originally reported by dev.to