[y-partyserver] provider.destroy() leaks reconnect timer, hanging Node processes and delaying GC
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 65/100
- issue の種類
- バグ
- 明瞭さ
- おおむね明確
- 活発さ
- 静か
- 技術スタック
- node.js, typescript
- 領域
- backend, networking
調査の方向性
y-partyserver/providerのエントリーポイントから開始し、WebSocketのcloseイベントと再接続のスケジューリングを通じてWebsocketProvider.destroy()を追跡します。issueのNode.js再現スクリプトを実行し、providerを破棄した後にイベントループを開いたままにする再接続タイマーが残らないこと、またプロセスが遅延なしに終了することを確認します。
索引モデルが issue の本文から書いたものです。
説明
I maintain YAOS a local-first sync engine running inside Obsidian, built on DOs and y-partyserver. While debugging a CI pipeline that inexplicably took 140 seconds instead of 36 seconds, we discovered that y-partyserver is leaking timers directly into the event loop every time a connection is torn down.
The Bug
When provider.destroy() is called on a WebsocketProvider in y-partyserver, the WebSocket's onclose event listener unconditionally queues a reconnect timer via setTimeout(setupWS, backoff, provider).
While the setupWS callback correctly checks this.shouldConnect and aborts (meaning it doesn't actually reconnect), the setTimeout handle itself is never stored or cleared during the destroy() lifecycle.
The Real-World Impact
-
Delayed Garbage Collection (Electron/SPA): In long-lived environments like ours, the setTimeout closure retains the entire provider instance and its massive associated Y.Doc in memory until the timer naturally fires (up to 2.5s). In environments with flapping networks where connections are repeatedly destroyed and recreated, this creates a massive GC backlog and stutters the UI thread.
-
Node.js / CI Hangs: The Node event loop refuses to exit until the backoff timer fires. In test suites that instantiate and destroy multiple providers, this compounds into massive CI delays, forcing developers to use process.exit(0) hacks just to allow scripts to terminate cleanly.
This issue is inherited DNA from y-websocket. The exact same architectural flaw was reported upstream 6 months ago (see yjs/y-websocket#198), but it has not merged. Since y-partyserver ships its own adapted provider implementation, it needs to be patched here.
Steps to Reproduce
Running this Node.js script proves the event loop is held hostage by the leaked timer, even after the provider is explicitly destroyed:
import YSyncProvider from "y-partyserver/provider";
import WebSocket from "ws";
async function run() {
const ydoc = new Y.Doc();
const provider = new YSyncProvider("ws://127.0.0.1:8787", "room", ydoc, {
WebSocketPolyfill: WebSocket
});
// Wait for initial connection logic
await new Promise(r => setTimeout(r, 100));
console.log("Destroying provider...");
provider.destroy();
// Wait a tick for the ws 'close' event to fire and schedule the leak
await new Promise(r => setTimeout(r, 100));
const handles = process._getActiveHandles().filter(
h => h.constructor.name === 'Timeout' || h.constructor.name === 'TimerWrap'
);
console.log(`Active timers preventing exit: ${handles.length}`);
// Process hangs here for up to 2.5 seconds instead of exiting immediately
}
run();
- 主要言語
- TypeScript
- スター
- 1.3k
- フォーク
- 84
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
cloudflare/partykit のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
cloudflare/partykit#425 · コメント 1 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
cloudflare/partykit#424 · コメント 1 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
cloudflare/partykit#423 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
cloudflare/partykit#419 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
cloudflare/partykit#411 ·
cloudflare/partykit の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
CopilotKit/openmuse#215 ·
メンテナーはふだん 3 日以内に返信
-
b:minor bug
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
software-mansion/argent#1698 ·
メンテナーはふだん 1 日以内に返信
-
e2e-failure ready-to-code
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
redhat-developer/rhdh-plugin-export-overlays#4624 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信