Merge pull request #4153 from overleaf/bg-limit-worker-pdf-requests

limit pdf requests from service worker

GitOrigin-RevId: adb83b03325324a92567a2f7983d5cd6c3ea901a
This commit is contained in:
Brian Gough 2021-06-08 13:41:54 +01:00 committed by Copybot
parent 1c4c518b7b
commit d61d714da8

View file

@ -1,7 +1,8 @@
import { v4 as uuid } from 'uuid' import { v4 as uuid } from 'uuid'
const COMPILE_REQUEST_MATCHER = /^\/project\/[0-9a-f]{24}\/compile$/ const COMPILE_REQUEST_MATCHER = /^\/project\/[0-9a-f]{24}\/compile$/
const PDF_JS_CHUNK_SIZE = 128 * 1024 const PDF_JS_CHUNK_SIZE = 128 * 1024
const MAX_SUBREQUEST_COUNT = 8
const MAX_SUBREQUEST_BYTES = 4 * PDF_JS_CHUNK_SIZE
const PDF_FILES = new Map() const PDF_FILES = new Map()
const METRICS = { const METRICS = {
@ -44,6 +45,15 @@ function trackChunkVerify({ sizeDiffers, mismatch, success }) {
} }
} }
/**
* @param {Array} chunks
*/
function countBytes(chunks) {
return chunks.reduce((totalBytes, chunk) => {
return totalBytes + (chunk.end - chunk.start)
}, 0)
}
/** /**
* @param {FetchEvent} event * @param {FetchEvent} event
*/ */
@ -140,9 +150,26 @@ function processPdfRequest(
.map(i => parseInt(i, 10)) .map(i => parseInt(i, 10))
const end = last + 1 const end = last + 1
// Check that handling the range request won't trigger excessive subrequests,
// (to avoid unwanted latency compared to the original request).
const chunks = getMatchingChunks(file.ranges, start, end) const chunks = getMatchingChunks(file.ranges, start, end)
const dynamicChunks = getInterleavingDynamicChunks(chunks, start, end) const dynamicChunks = getInterleavingDynamicChunks(chunks, start, end)
const chunksSize = countBytes(chunks)
if (chunks.length + dynamicChunks.length > MAX_SUBREQUEST_COUNT) {
// fall back to the original range request when splitting the range creates
// too many subrequests.
return
}
if (
chunksSize > MAX_SUBREQUEST_BYTES &&
!(dynamicChunks.length === 0 && chunks.length === 1)
) {
// fall back to the original range request when a very large amount of
// object data would be requested, unless it is the only object in the
// request.
return
}
// URL prefix is /project/:id/user/:id/build/... or /project/:id/build/... // URL prefix is /project/:id/user/:id/build/... or /project/:id/build/...
// for authenticated and unauthenticated users respectively. // for authenticated and unauthenticated users respectively.