Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

[y-partyserver] provider.destroy() leaks reconnect timer, hanging Node processes and delaying GC

Aperta Adatta ai principianti
#402 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
65/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Tranquilla
Stack tecnologico
node.js, typescript

Direzione di ricerca

Inizia dal punto di ingresso y-partyserver/provider e segui WebsocketProvider.destroy() attraverso l’evento di chiusura di WebSocket e la pianificazione della riconnessione. Esegui lo script di riproduzione Node.js dell’issue, quindi verifica che la distruzione del provider non lasci alcun timer di riconnessione a mantenere aperto il ciclo degli eventi e che il processo termini senza il ritardo.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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

  1. 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.

  2. 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();
Lingua principale
TypeScript
Stelle
1.3k
Fork
84
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di cloudflare/partykit

Tutte le issue di cloudflare/partykit

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.