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

Windows: ConoutConnection worker thread prevents Node.js from exiting after kill()

Aperta
#887 4 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
70/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Tranquilla
Stack tecnologico
node.js, typescript
Ambito
cli

Direzione di ricerca

Riproduci il blocco di Windows ConPTY con lo script Node.js fornito, quindi esamina src/windowsConoutConnection.ts, src/worker/conoutSocketWorker.ts e src/windowsPtyAgent.ts alle righe indicate. Controlla il worker, i socket e i timeout di cleanup coinvolti dopo kill(). Il lavoro è completato quando il processo termina dopo l’evento exit senza richiedere process.exit(), mentre il cleanup continua a completarsi quando altro lavoro mantiene attivo l’event loop.

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

Descrizione

Environment

  • OS: Windows (ConPTY path)
  • node-pty version: 1.2.0-beta.10
  • Node.js: v22.22.0

Description

After calling kill() on a Windows PTY and awaiting its exit event, Node.js cannot exit because active handles remain on the event loop. This forces consumers to call process.exit() as a workaround.

The root cause is that the ConoutConnection worker thread, its internal sockets, and several cleanup timeouts are never unref()'d. There is no .unref() call anywhere in node-pty's source.

Reproduction

const pty = require('node-pty');

const term = pty.spawn('cmd.exe', [], { cols: 80, rows: 24 });

term.onExit(() => {
  console.log('exited');
  // Node.js should exit here, but it hangs indefinitely
});

setTimeout(() => term.kill(), 500);

Expected: process exits after "exited" is logged.
Actual: process hangs indefinitely.

Root cause

There are three categories of handles keeping the event loop alive after kill():

1. Worker thread (primary)

src/windowsConoutConnection.ts:47 — the Worker is created but never unref()'d:

this._worker = new Worker(join(scriptPath, 'worker/conoutSocketWorker.js'), { workerData });

The worker runs a net.Socket + net.createServer (src/worker/conoutSocketWorker.ts:11-17) that are also never unref()'d. Both the worker thread and its internal sockets keep the event loop alive.

2. Drain timeout

When dispose() is called, it schedules a 1-second timeout before terminating the worker (src/windowsConoutConnection.ts:76):

this._drainTimeout = setTimeout(() => this._destroySocket(), FLUSH_DATA_INTERVAL);

This timeout is not unref()'d, keeping the event loop alive for the duration.

A similar un-unref()'d timeout exists in WindowsPtyAgent._flushDataAndCleanUp() (src/windowsPtyAgent.ts:179):

this._closeTimeout = setTimeout(() => this._cleanUpProcess(), FLUSH_DATA_INTERVAL);
3. I/O sockets

_outSocket and _inSocket in WindowsPtyAgent (src/windowsPtyAgent.ts:78-94) are never unref()'d.

Suggested fix

Call unref() on handles that shouldn't prevent process exit:

// windowsConoutConnection.ts — constructor
this._worker = new Worker(join(scriptPath, 'worker/conoutSocketWorker.js'), { workerData });
this._worker.unref();

// windowsConoutConnection.ts — _drainDataAndClose
this._drainTimeout = setTimeout(() => this._destroySocket(), FLUSH_DATA_INTERVAL);
this._drainTimeout.unref();

// windowsPtyAgent.ts — constructor (sockets)
this._outSocket.unref();
this._inSocket.unref();

// windowsPtyAgent.ts — _flushDataAndCleanUp
this._closeTimeout = setTimeout(() => this._cleanUpProcess(), FLUSH_DATA_INTERVAL);
this._closeTimeout.unref();

This ensures cleanup completes if other work keeps the event loop alive, but doesn't prevent the process from exiting when everything else is done.

Lingua principale
TypeScript
Stelle
2k
Fork
337
Merge medio
21h 58m
PR unite (30g)
3

Guida per i contributori

Apri la guida per i contributori

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 microsoft/node-pty

Tutte le issue di microsoft/node-pty

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.