Merge pull request #10694 from Snuffleupagus/main-thread-progressiveDataLength

Avoid dispatching range requests to fetch PDF data that's already loaded with streaming (PR 10675 follow-up)
This commit is contained in:
Tim van der Meij 2019-04-13 17:15:01 +02:00 committed by GitHub
commit 17de90b88a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 49 additions and 8 deletions

View File

@ -1839,6 +1839,21 @@ class WorkerTransport {
const rangeReader = const rangeReader =
this._networkStream.getRangeReader(data.begin, data.end); this._networkStream.getRangeReader(data.begin, data.end);
// When streaming is enabled, it's possible that the data requested here
// has already been fetched via the `_fullRequestReader` implementation.
// However, given that the PDF data is loaded asynchronously on the
// main-thread and then sent via `postMessage` to the worker-thread,
// it may not have been available during parsing (hence the attempt to
// use range requests here).
//
// To avoid wasting time and resources here, we'll thus *not* dispatch
// range requests if the data was already loaded but has not been sent to
// the worker-thread yet (which will happen via the `_fullRequestReader`).
if (!rangeReader) {
sink.close();
return;
}
sink.onPull = () => { sink.onPull = () => {
rangeReader.read().then(function({ value, done, }) { rangeReader.read().then(function({ value, done, }) {
if (done) { if (done) {

View File

@ -42,6 +42,10 @@ class PDFFetchStream {
this._rangeRequestReaders = []; this._rangeRequestReaders = [];
} }
get _progressiveDataLength() {
return (this._fullRequestReader ? this._fullRequestReader._loaded : 0);
}
getFullReader() { getFullReader() {
assert(!this._fullRequestReader); assert(!this._fullRequestReader);
this._fullRequestReader = new PDFFetchStreamReader(this); this._fullRequestReader = new PDFFetchStreamReader(this);
@ -49,6 +53,9 @@ class PDFFetchStream {
} }
getRangeReader(begin, end) { getRangeReader(begin, end) {
if (end <= this._progressiveDataLength) {
return null;
}
let reader = new PDFFetchStreamRangeReader(this, begin, end); let reader = new PDFFetchStreamRangeReader(this, begin, end);
this._rangeRequestReaders.push(reader); this._rangeRequestReaders.push(reader);
return reader; return reader;

View File

@ -54,19 +54,26 @@ class PDFNodeStream {
this.isFsUrl = this.url.protocol === 'file:'; this.isFsUrl = this.url.protocol === 'file:';
this.httpHeaders = (this.isHttp && source.httpHeaders) || {}; this.httpHeaders = (this.isHttp && source.httpHeaders) || {};
this._fullRequest = null; this._fullRequestReader = null;
this._rangeRequestReaders = []; this._rangeRequestReaders = [];
} }
get _progressiveDataLength() {
return (this._fullRequestReader ? this._fullRequestReader._loaded : 0);
}
getFullReader() { getFullReader() {
assert(!this._fullRequest); assert(!this._fullRequestReader);
this._fullRequest = this.isFsUrl ? this._fullRequestReader = this.isFsUrl ?
new PDFNodeStreamFsFullReader(this) : new PDFNodeStreamFsFullReader(this) :
new PDFNodeStreamFullReader(this); new PDFNodeStreamFullReader(this);
return this._fullRequest; return this._fullRequestReader;
} }
getRangeReader(start, end) { getRangeReader(start, end) {
if (end <= this._progressiveDataLength) {
return null;
}
let rangeReader = this.isFsUrl ? let rangeReader = this.isFsUrl ?
new PDFNodeStreamFsRangeReader(this, start, end) : new PDFNodeStreamFsRangeReader(this, start, end) :
new PDFNodeStreamRangeReader(this, start, end); new PDFNodeStreamRangeReader(this, start, end);
@ -75,8 +82,8 @@ class PDFNodeStream {
} }
cancelAllRequests(reason) { cancelAllRequests(reason) {
if (this._fullRequest) { if (this._fullRequestReader) {
this._fullRequest.cancel(reason); this._fullRequestReader.cancel(reason);
} }
let readers = this._rangeRequestReaders.slice(0); let readers = this._rangeRequestReaders.slice(0);

View File

@ -76,6 +76,10 @@ var PDFDataTransportStream = (function PDFDataTransportStreamClosure() {
} }
}, },
get _progressiveDataLength() {
return (this._fullRequestReader ? this._fullRequestReader._loaded : 0);
},
_onProgress: function PDFDataTransportStream_onDataProgress(evt) { _onProgress: function PDFDataTransportStream_onDataProgress(evt) {
if (evt.total === undefined && this._rangeReaders.length > 0) { if (evt.total === undefined && this._rangeReaders.length > 0) {
// Reporting to first range reader. // Reporting to first range reader.
@ -115,6 +119,9 @@ var PDFDataTransportStream = (function PDFDataTransportStreamClosure() {
}, },
getRangeReader: function PDFDataTransportStream_getRangeReader(begin, end) { getRangeReader: function PDFDataTransportStream_getRangeReader(begin, end) {
if (end <= this._progressiveDataLength) {
return null;
}
var reader = new PDFDataTransportStreamRangeReader(this, begin, end); var reader = new PDFDataTransportStreamRangeReader(this, begin, end);
this._pdfDataRangeTransport.requestDataRange(begin, end); this._pdfDataRangeTransport.requestDataRange(begin, end);
this._rangeReaders.push(reader); this._rangeReaders.push(reader);
@ -141,6 +148,10 @@ var PDFDataTransportStream = (function PDFDataTransportStreamClosure() {
this._done = progressiveDone || false; this._done = progressiveDone || false;
this._filename = null; this._filename = null;
this._queuedChunks = queuedChunks || []; this._queuedChunks = queuedChunks || [];
this._loaded = 0;
for (const chunk of this._queuedChunks) {
this._loaded += chunk.byteLength;
}
this._requests = []; this._requests = [];
this._headersReady = Promise.resolve(); this._headersReady = Promise.resolve();
stream._fullRequestReader = this; stream._fullRequestReader = this;
@ -155,9 +166,10 @@ var PDFDataTransportStream = (function PDFDataTransportStreamClosure() {
if (this._requests.length > 0) { if (this._requests.length > 0) {
var requestCapability = this._requests.shift(); var requestCapability = this._requests.shift();
requestCapability.resolve({ value: chunk, done: false, }); requestCapability.resolve({ value: chunk, done: false, });
return; } else {
this._queuedChunks.push(chunk);
} }
this._queuedChunks.push(chunk); this._loaded += chunk.byteLength;
}, },
get headersReady() { get headersReady() {