From 6d78a810b94808cd61b8b706aff3310895a7d0eb Mon Sep 17 00:00:00 2001 From: Julien Fontanet Date: Tue, 20 Dec 2016 15:36:54 +0100 Subject: [PATCH] perf(RemoteHandlerAbstract/createReadStream): optimise code - avoid async function: overhead with transpilation - do as much as possible in parallel - fix: do not add length property in range mode --- src/remote-handlers/abstract.js | 53 +++++++++++++++++++-------------- src/utils.js | 2 +- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/remote-handlers/abstract.js b/src/remote-handlers/abstract.js index 4fec87faa..7edb2761d 100644 --- a/src/remote-handlers/abstract.js +++ b/src/remote-handlers/abstract.js @@ -112,42 +112,51 @@ export default class RemoteHandlerAbstract { throw new Error('Not implemented') } - async createReadStream (file, { + createReadStream (file, { checksum = false, ignoreMissingChecksum = false, ...options } = {}) { - const streamP = this._createReadStream(file, options).then(async stream => { - await eventToPromise(stream, 'readable') + const streamP = this._createReadStream(file, options).then(stream => { + // detect early errors + let promise = eventToPromise(stream, 'readable') - if (stream.length === undefined) { - stream.length = await this.getSize(file)::pCatch(noop) + // try to add the length prop if missing and not a range stream + if ( + stream.length === undefined && + options.end === undefined && + options.start === undefined + ) { + promise = Promise.all([ promise, this.getSize(file).then(size => { + stream.length = size + }, noop) ]) } - return stream + return promise.then(() => stream) }) if (!checksum) { return streamP } - try { - checksum = await this.readFile(`${file}.checksum`) - } catch (error) { - if (error.code === 'ENOENT' && ignoreMissingChecksum) { - return streamP + // avoid a unhandled rejection warning + streamP.catch(noop) + + return this.readFile(`${file}.checksum`).then( + checksum => streamP.then(stream => { + const { length } = stream + stream = validChecksumOfReadStream(stream, String(checksum).trim()) + stream.length = length + + return stream + }), + error => { + if (ignoreMissingChecksum && error && error.code === 'ENOENT') { + return streamP + } + throw error } - - throw error - } - - let stream = await streamP - - const { length } = stream - stream = validChecksumOfReadStream(stream, checksum.toString()) - stream.length = length - - return stream + ) } async _createReadStream (file, options) { diff --git a/src/utils.js b/src/utils.js index d321547d2..0a5ad807e 100644 --- a/src/utils.js +++ b/src/utils.js @@ -166,7 +166,7 @@ export const validChecksumOfReadStream = (stream, expectedChecksum) => { const checksum = `$${algorithmId}$$${hash.digest('hex')}` callback( - checksum.trim() !== expectedChecksum.trim() + checksum !== expectedChecksum ? new Error(`Bad checksum (${checksum}), expected: ${expectedChecksum}`) : null )