nodejs / nodejs/node

Partially consuming fs.ReadStream closes file handle despite `autoClose: false`

Offen
#45,721 7 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

fs stream
Vorherrschende Sprache
JavaScript
Sterne
122k
Forks
37.3k
Ø Merge
4 T. 2 Std.
Gemergte PRs (30 T.)
283

Beschreibung

Version

v19.2.0, v14.21.1

Platform

Linux wolf-x1c6 5.15.0-53-generic #59-Ubuntu SMP Mon Oct 17 18:53:30 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Subsystem

No response

What steps will reproduce the bug?
import fsPromises from 'node:fs/promises'

const fh = await fsPromises.open('example.txt')
fh.on('close', () => {throw new Error('handle closed!')})

const stream = fh.createReadStream({
	autoClose: false,
})

for await (const chunk of stream) {
	break
}

// Give the event loop a breather: this seems to be where the close happens
await new Promise(resolve => setTimeout(resolve, 10))

console.log('fd', fh.fd) // = -1; stream closed
How often does it reproduce? Is there a required condition?

Always

What is the expected behavior?

FileHandle.createReadStream({autoClose: false}) should result in the file handle not being automatically closed when the stream is destroyed.

What do you see instead?

Using fs.ReadStream[Symbol.asyncIterator] seems to unconditionally close the file handle (after a small delay; I guess at the end of the event loop or something? but haven't dug in; just noted the setTimeout above is necessary to reproduce) despite {autoClose: false} being passed to FileHandle.createReadStream().

This seems to be the result of the underlying readable.destroy() also closing the file handle; but it means that, as far as I can tell, there's no way to only partially consume an fs.ReadStream created from a file handle without either closing the handle or leaking the stream.

Additional information

No response

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne mit der bereitgestellten Reproduktion und verfolge FileHandle.createReadStream(), fs.ReadStream[Symbol.asyncIterator] und readable.destroy() während einer partiellen asynchronen Iteration. Bestätige, wann das Dateihandle trotz autoClose: false geschlossen wird, und stelle dann sicher, dass das Handle nach dem Abbruch der Iteration geöffnet bleibt, ohne den Stream zu leaken.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
javascript, nodejs
Bereich
operating-systems
Issue-Typ
Bug
Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Aktivitätsstatus
Ruhig
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
48/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.