Skip to content

Commit

Permalink
perf: optimize Readable.dump
Browse files Browse the repository at this point in the history
  • Loading branch information
ronag committed Nov 6, 2023
1 parent 1541173 commit b70ae8a
Showing 1 changed file with 30 additions and 20 deletions.
50 changes: 30 additions & 20 deletions lib/api/readable.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ const kBody = Symbol('kBody')
const kAbort = Symbol('abort')
const kContentType = Symbol('kContentType')

const noop = () => {}

module.exports = class BodyReadable extends Readable {
constructor ({
resume,
Expand Down Expand Up @@ -152,34 +154,42 @@ module.exports = class BodyReadable extends Readable {
async dump (opts) {
let limit = opts && Number.isFinite(opts.limit) ? opts.limit : 262144
const signal = opts && opts.signal
const abortFn = () => {
this.destroy()
}

let signalListenerCleanup
if (signal) {
if (typeof signal !== 'object' || !('aborted' in signal)) {
throw new InvalidArgumentError('signal must be an AbortSignal')
}
util.throwIfAborted(signal)
signalListenerCleanup = util.addAbortListener(signal, abortFn)
}
try {
for await (const chunk of this) {
util.throwIfAborted(signal)
limit -= Buffer.byteLength(chunk)
if (limit < 0) {
return
}
}
} catch {
util.throwIfAborted(signal)
} finally {
if (typeof signalListenerCleanup === 'function') {
signalListenerCleanup()
} else if (signalListenerCleanup) {
signalListenerCleanup[Symbol.dispose]()
}

if (this.closed) {
return Promise.resolve(null)
}

return new Promise((resolve, reject) => {
signalListenerCleanup = util.addAbortListener(signal, () => {
this.destroy()
})

this
.on('close', function () {
signalListenerCleanup()
if (signal?.aborted) {
reject(signal.reason || Object.assign(new Error('The operation was aborted'), { name: 'AbortError' }))
} else {
resolve(null)
}
})
.on('error', noop)
.on('data', (chunk) => {
limit -= chunk.length
if (limit <= 0) {
this.destroy()
}
})
.resume()
})
}
}

Expand Down

0 comments on commit b70ae8a

Please sign in to comment.