stream: use finished for pump

Re-use existing compat logic for pump by using
finished.

PR-URL: https://github.com/nodejs/node/pull/39203
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
This commit is contained in:
Robert Nagy committed 2021-07-02 10:12:45 +02:00
1 parent 97bd33cefd
commit 320339630d
2 files changed
+32 -73

No files matched your search

+32 -40
View File
@@ -20,20 +20,16 @@ const {
ERR_INVALID_RETURN_VALUE,
ERR_MISSING_ARGS,
ERR_STREAM_DESTROYED,
ERR_STREAM_PREMATURE_CLOSE,
},
} = require('internal/errors');
const { validateCallback } = require('internal/validators');
function noop() {}
const {
isIterable,
isReadable,
isStream,
} = require('internal/streams/utils');
const assert = require('internal/assert');
let PassThrough;
let Readable;
@@ -109,62 +105,58 @@ async function* fromReadable(val) {
async function pump(iterable, writable, finish) {
let error;
let callback = noop;
let onresolve = null;
const resume = (err) => {
error = aggregateTwoErrors(error, err);
const _callback = callback;
callback = noop;
_callback();
};
const onClose = () => {
resume(new ERR_STREAM_PREMATURE_CLOSE());
if (err) {
error = err;
}
if (onresolve) {
const callback = onresolve;
onresolve = null;
callback();
}
};
const waitForDrain = () => new Promise((resolve) => {
assert(callback === noop);
if (error || writable.destroyed) {
resolve();
const wait = () => new Promise((resolve, reject) => {
if (error) {
reject(error);
} else {
callback = resolve;
onresolve = () => {
if (error) {
reject(error);
} else {
resolve();
}
};
}
});
writable
.on('drain', resume)
.on('error', resume)
.on('close', onClose);
writable.on('drain', resume);
const cleanup = eos(writable, { readable: false }, resume);
try {
if (writable.writableNeedDrain) {
await waitForDrain();
}
if (error) {
return;
await wait();
}
for await (const chunk of iterable) {
if (!writable.write(chunk)) {
await waitForDrain();
await wait();
}
if (error) {
return;
}
}
if (error) {
return;
}
writable.end();
await wait();
finish();
} catch (err) {
error = aggregateTwoErrors(error, err);
finish(error !== err ? aggregateTwoErrors(error, err) : err);
} finally {
writable
.off('drain', resume)
.off('error', resume)
.off('close', onClose);
finish(error);
cleanup();
writable.off('drain', resume);
}
}
-33
View File
@@ -1387,36 +1387,3 @@ const net = require('net');
assert.strictEqual(res, content);
}));
}
{
const writableLike = new Stream();
writableLike.writableNeedDrain = true;
pipeline(
async function *() {},
writableLike,
common.mustCall((err) => {
assert.strictEqual(err.code, 'ERR_STREAM_PREMATURE_CLOSE');
})
);
writableLike.emit('close');
}
{
const writableLike = new Stream();
writableLike.write = () => false;
pipeline(
async function *() {
yield null;
yield null;
},
writableLike,
common.mustCall((err) => {
assert.strictEqual(err.code, 'ERR_STREAM_PREMATURE_CLOSE');
})
);
writableLike.emit('close');
}