Skip to content

Prevent double buffering when converting Readable to ReadableStream #48636

@hbgl

Description

@hbgl

Version

v18.16.0

Platform

Microsoft Windows NT 10.0.19045.0 x64

Subsystem

webstreams

What steps will reproduce the bug?

When creating a ReadableStream from a Readable via Readable.toWeb, the total amount of internally buffered data is twice as much as expected.

To reproduce, run this program:

// File index.mjs
import { Readable } from 'node:stream';

let i = 1;
function* generator() {
    for (;;) {
        yield i;
        i++;
    }
}

const readable = Readable.from(generator(), { objectMode: true, highWaterMark: 8 });
const stream = Readable.toWeb(readable);
const reader = stream.getReader();

await reader.read();

// Prints: Pulled 17 items.
console.log(`Pulled ${i} items`);

How often does it reproduce? Is there a required condition?

There is no special condition.

What is the expected behavior? Why is that the expected behavior?

The expected behavior is to only have a single internal buffer.

What do you see instead?

Both the Readable and the attached ReadableStream buffer data internally.

Additional information

I believe the issue is that the highWaterMark from the node Readable is copied to the ReadableStream queuing strategy. Since the two streams each have a buffer, the amount of buffered data is effectively doubled. This is the code in question:

https://github.com/nodejs/node/blob/1936160c31afc9780e4365de033789f39b7cbc0c/lib/internal/webstreams/adapters.js#L409C1-L427

My suggested fix would be to disable buffering in the ReadableStream by setting its highWaterMark to zero.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions