From f947b549e46b99687e25e4db5636d49e3d041544 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Wed, 18 Mar 2026 07:42:56 +0100 Subject: [PATCH] [clsi-perf] migrate to compile from history mode (#32234) * [clsi] only download history snapshot from clsi-cache when enabled * [clsi-perf] migrate to compile from history mode GitOrigin-RevId: 2dd54e032bd85d6335488741c039a5a1bd60090d --- services/clsi/app/js/HistoryResourceWriter.js | 55 ++++++++++++++----- services/clsi/app/js/RequestParser.js | 7 +++ 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/services/clsi/app/js/HistoryResourceWriter.js b/services/clsi/app/js/HistoryResourceWriter.js index ec05101d74..c2f766fdbc 100644 --- a/services/clsi/app/js/HistoryResourceWriter.js +++ b/services/clsi/app/js/HistoryResourceWriter.js @@ -74,9 +74,15 @@ function isENOENT(err) { * @param {string} projectId * @param {string} userId * @param {number} remoteBaseVersion + * @param {boolean} populateClsiCache * @return {Promise<{rawSnapshot: import('overleaf-editor-core/lib/types.js').RawSnapshot, globalBlobs: string[], fullSync: boolean,localBaseVersion: number}>} */ -async function loadSnapshot(projectId, userId, remoteBaseVersion) { +async function loadSnapshot( + projectId, + userId, + remoteBaseVersion, + populateClsiCache +) { const { path, resyncPath } = snapshotPath(projectId, userId) let maxLocalBaseVersion = -1 for (const candidate of [path, resyncPath]) { @@ -97,19 +103,25 @@ async function loadSnapshot(projectId, userId, remoteBaseVersion) { } } } - try { - return await loadSnapshotFromClsiCache(projectId, userId, remoteBaseVersion) - } catch (err) { - if (err instanceof Errors.MissingUpdatesError) { - maxLocalBaseVersion = Math.max( - maxLocalBaseVersion, - err.info.baseHistoryVersion - ) - } else if (!isENOENT(err)) { - logger.warn( - { err, projectId, userId }, - 'compile from cache: cannot download from clsi-cache' + if (populateClsiCache) { + try { + return await loadSnapshotFromClsiCache( + projectId, + userId, + remoteBaseVersion ) + } catch (err) { + if (err instanceof Errors.MissingUpdatesError) { + maxLocalBaseVersion = Math.max( + maxLocalBaseVersion, + err.info.baseHistoryVersion + ) + } else if (!isENOENT(err)) { + logger.warn( + { err, projectId, userId }, + 'compile from cache: cannot download from clsi-cache' + ) + } } } throw new Errors.MissingUpdatesError('needs more updates', { @@ -349,7 +361,12 @@ export async function syncResourcesToDisk( let fullSync = true try { ;({ rawSnapshot, globalBlobs, fullSync, localBaseVersion } = - await loadSnapshot(projectId, userId, remoteBaseVersion)) + await loadSnapshot( + projectId, + userId, + remoteBaseVersion, + request.populateClsiCache + )) source = fullSync ? 'clsi-cache' : 'local' logger.debug( { projectId, userId, localBaseVersion, remoteBaseVersion }, @@ -424,6 +441,7 @@ export async function syncResourcesToDisk( const blobStore = new BlobStore( request.historyId, request.filestoreBlobPrefix, + request.clsiPerfVariant, globalBlobs ) const loadEagerStart = performance.now() @@ -509,15 +527,19 @@ class BlobStore { #globalBlobs /** @type {string} */ #filestoreBlobPrefix + /** @type {string} */ + #clsiPerfVariant /** * @param {string} historyId * @param {string} filestoreBlobPrefix + * @param {string} clsiPerfVariant * @param {string[]} globalBlobs */ - constructor(historyId, filestoreBlobPrefix, globalBlobs) { + constructor(historyId, filestoreBlobPrefix, clsiPerfVariant, globalBlobs) { this.#historyId = historyId this.#filestoreBlobPrefix = filestoreBlobPrefix + this.#clsiPerfVariant = clsiPerfVariant this.#globalBlobs = globalBlobs } @@ -529,6 +551,9 @@ class BlobStore { const u = new URL(Settings.apis.filestore.url) if (this.#filestoreBlobPrefix) { u.pathname = `${this.#filestoreBlobPrefix}/${hash}` + } else if (this.#clsiPerfVariant) { + u.host = Settings.apis.clsiPerf.host + u.pathname = `/variant/${this.#clsiPerfVariant}/hash/${hash}` } else if (this.#globalBlobs.includes(hash)) { u.pathname = `/history/global/hash/${hash}` } else { diff --git a/services/clsi/app/js/RequestParser.js b/services/clsi/app/js/RequestParser.js index 4d153799a9..5168d72e83 100644 --- a/services/clsi/app/js/RequestParser.js +++ b/services/clsi/app/js/RequestParser.js @@ -167,6 +167,13 @@ function parse(body, callback) { response.filestoreBlobPrefix = _checkPath(compile.filestoreBlobPrefix) } + // clsi-perf + response.clsiPerfVariant = _parseAttribute( + 'clsiPerfVariant', + compile.options.clsiPerfVariant, + { type: 'string' } + ) + const rootResourcePath = _parseAttribute( 'rootResourcePath', compile.rootResourcePath,