Why destroy stream in error?
Asked Answered
L

1

6

I see some modules that pipe readable streams in writable streams, and if any error occurr, they use the destroy method:

const readable = fs.createReadStream("file");
const writable = fs.createWriteStream("file2");

readable.pipe(writable);

readable.on("error", (error) => {
  readable.destroy();
  writable.destroy();
  writable.removeListener("close");
  callback(error);
});

writable.on("error", (error) => {
  readable.destroy();
  writable.destroy();
  writable.removeListener("close");
  callback(error);
});

What is the necessity of destroying the streams and removing the close event on the writable stream? If i don't do that, what could happen?

Thanks.

Longeron answered 30/3, 2017 at 14:0 Comment(0)
M
1

I believe this is necessary to avoid memory leaks. As per the Node.js documentation on the readable.pipe() method,

One important caveat is that if the Readable stream emits an error during processing, the Writable destination is not closed automatically. If an error occurs, it will be necessary to manually close each stream in order to prevent memory leaks.

In the script below, comment out the line w.destroy(err) and notice none of the Writeable events emit. Not sure why Node.js designers chose to not automatically destroy the Writeable's, maybe they didn't want Stream.pipe() to be too opinionated.

const r = new Readable({
      objectMode: true,
      read() {
        try {
          this.push(JSON.parse('{"prop": "I am the data"'))
          this.push(null) // make sure we let Writeable's know there's no more to read
        } catch (e) {
          console.error(`Problem encountered while reading data`, e)
          this.destroy(e)
        }
      }
    }).on('error', (err) => {
      console.log(`Reader error: ${err}`)
      w.destroy(err)
      done()
    })

    const w = new Writable({
      objectMode: true,
      write(chunk, encoding, callback) {
        callback()
      }
    }).on('error', (err) => {
      console.error(`Writer error: ${err}`)
    })
      .on('close', () => {
        console.error(`Writer close`)
      })
      .on('finish', () => {
        console.error(`Writer finish`)
      })
    r.pipe(w)
Myth answered 7/5, 2021 at 2:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.