From 3c82d961bdf364a9591366e6eddc4746ae8f275b Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Mon, 9 Dec 2024 22:24:02 +0200 Subject: [PATCH] Batch extension version checks --- public/scripts/extensions.js | 37 +++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/public/scripts/extensions.js b/public/scripts/extensions.js index 9416c38e2..0229146b1 100644 --- a/public/scripts/extensions.js +++ b/public/scripts/extensions.js @@ -586,7 +586,6 @@ function generateExtensionHtml(name, manifest, isActive, isDisabled, isExternal, const isUserAdmin = isAdmin(); const extensionIcon = getExtensionIcon(); const displayName = manifest.display_name; - let displayVersion = manifest.version ? ` v${manifest.version}` : ''; const externalId = name.replace('third-party', ''); let originHtml = ''; if (isExternal) { @@ -632,7 +631,7 @@ function generateExtensionHtml(name, manifest, isActive, isDisabled, isExternal, ${originHtml} ${DOMPurify.sanitize(displayName)} - ${displayVersion} + ${modulesInfo} ${isExternal ? '' : ''} @@ -1032,6 +1031,29 @@ export function doDailyExtensionUpdatesCheck() { }, 1); } +const concurrencyLimit = 5; +let activeRequestsCount = 0; +const versionCheckQueue = []; + +function enqueueVersionCheck(fn) { + return new Promise((resolve, reject) => { + versionCheckQueue.push(() => fn().then(resolve).catch(reject)); + processVersionCheckQueue(); + }); +} + +function processVersionCheckQueue() { + if (activeRequestsCount >= concurrencyLimit || versionCheckQueue.length === 0) { + return; + } + activeRequestsCount++; + const fn = versionCheckQueue.shift(); + fn().finally(() => { + activeRequestsCount--; + processVersionCheckQueue(); + }); +} + /** * Performs a manual check for updates on all 3rd-party extensions. * @param {AbortSignal} abortSignal Signal to abort the operation @@ -1041,7 +1063,7 @@ async function checkForUpdatesManual(abortSignal) { const promises = []; for (const id of Object.keys(manifests).filter(x => x.startsWith('third-party'))) { const externalId = id.replace('third-party', ''); - const promise = new Promise(async (resolve, reject) => { + const promise = enqueueVersionCheck(async () => { try { const data = await getExtensionVersion(externalId, abortSignal); const extensionBlock = document.querySelector(`.extension_block[data-name="${externalId}"]`); @@ -1072,10 +1094,8 @@ async function checkForUpdatesManual(abortSignal) { versionElement.textContent += ` (${branch}-${commitHash.substring(0, 7)})`; } } - resolve(); } catch (error) { console.error('Error checking for extension updates', error); - reject(); } }); promises.push(promise); @@ -1111,17 +1131,16 @@ async function checkForExtensionUpdates(force) { console.debug(`Skipping global extension: ${manifest.display_name} (${id}) for non-admin user`); continue; } + if (manifest.auto_update && id.startsWith('third-party')) { - const promise = new Promise(async (resolve, reject) => { + const promise = enqueueVersionCheck(async () => { try { const data = await getExtensionVersion(id.replace('third-party', '')); - if (data.isUpToDate === false) { + if (!data.isUpToDate) { updatesAvailable.push(manifest.display_name); } - resolve(); } catch (error) { console.error('Error checking for extension updates', error); - reject(); } }); promises.push(promise);