1
0
Эх сурвалжийг харах

implemented pool of workers (cf issue #204)

Gildas 6 жил өмнө
parent
commit
de487ca821

+ 44 - 10
extension/core/bg/business.js

@@ -68,6 +68,9 @@ singlefile.extension.core.bg.business = (() => {
 
 	initScripts();
 
+	const pendingSaves = new Map();
+	let maxParallelWorkers;
+
 	return { saveTab };
 
 	async function saveTab(tab, options = {}) {
@@ -75,6 +78,7 @@ singlefile.extension.core.bg.business = (() => {
 		const autosave = singlefile.extension.core.bg.autosave;
 		const tabs = singlefile.extension.core.bg.tabs;
 		const ui = singlefile.extension.ui.bg.main;
+		maxParallelWorkers = (await config.get()).maxParallelWorkers;
 		if (singlefile.extension.core.bg.util.isAllowedURL(tab.url)) {
 			await initScripts();
 			const tabId = tab.id;
@@ -82,16 +86,16 @@ singlefile.extension.core.bg.business = (() => {
 			options.tabIndex = tab.index;
 			try {
 				if (options.autoSave) {
-					const options = await config.getOptions(tab.url, true);
+					const tabOptions = await config.getOptions(tab.url, true);
 					if (autosave.isEnabled(tab)) {
-						await tabs.sendMessage(tabId, { method: "content.autosave", options });
+						await requestSaveTab(tabId, "content.autosave", tabOptions);
 					}
 				} else {
 					ui.onInitialize(tabId, options, 1);
-					const mergedOptions = await config.getOptions(tab.url);
-					Object.keys(options).forEach(key => mergedOptions[key] = options[key]);
+					const tabOptions = await config.getOptions(tab.url);
+					Object.keys(options).forEach(key => tabOptions[key] = options[key]);
 					let scriptsInjected;
-					if (!mergedOptions.removeFrames) {
+					if (!tabOptions.removeFrames) {
 						try {
 							await tabs.executeScript(tabId, { code: frameScript, allFrames: true, matchAboutBlank: true, runAt: "document_start" });
 						} catch (error) {
@@ -106,13 +110,13 @@ singlefile.extension.core.bg.business = (() => {
 						// ignored
 					}
 					if (scriptsInjected) {
-						ui.onInitialize(tabId, options, 2);
-						if (mergedOptions.frameId) {
-							await tabs.executeScript(tabId, { code: "document.documentElement.dataset.requestedFrameId = true", frameId: mergedOptions.frameId, matchAboutBlank: true, runAt: "document_start" });
+						ui.onInitialize(tabId, tabOptions, 2);
+						if (tabOptions.frameId) {
+							await tabs.executeScript(tabId, { code: "document.documentElement.dataset.requestedFrameId = true", frameId: tabOptions.frameId, matchAboutBlank: true, runAt: "document_start" });
 						}
-						await tabs.sendMessage(tabId, { method: "content.save", options: mergedOptions });
+						await requestSaveTab(tabId, "content.save", tabOptions);
 					} else {
-						ui.onForbiddenDomain(tab, options);
+						ui.onForbiddenDomain(tab, tabOptions);
 					}
 				}
 			} catch (error) {
@@ -122,6 +126,36 @@ singlefile.extension.core.bg.business = (() => {
 		}
 	}
 
+	function requestSaveTab(tabId, method, options) {
+		return new Promise((resolve, reject) => requestSaveTab(tabId, method, options, resolve, reject));
+
+		async function requestSaveTab(tabId, method, options, resolve, reject) {
+			if (pendingSaves.size < maxParallelWorkers) {
+				pendingSaves.set(tabId, { options, resolve, reject });
+				try {
+					await singlefile.extension.core.bg.tabs.sendMessage(tabId, { method, options });
+					pendingSaves.delete(tabId);
+					resolve();
+				} catch (error) {
+					pendingSaves.delete(tabId);
+					reject(error);
+				} finally {
+					next();
+				}
+			} else {
+				pendingSaves.set(tabId, { options, resolve, reject });
+			}
+		}
+
+		function next() {
+			if (pendingSaves.size) {
+				const [tabId, { resolve, reject, options }] = Array.from(pendingSaves)[0];
+				pendingSaves.delete(tabId);
+				requestSaveTab(tabId, method, options, resolve, reject);
+			}
+		}
+	}
+
 	async function initScripts() {
 		if (!contentScript && !frameScript && !modulesScript) {
 			[contentScript, frameScript, modulesScript] = await Promise.all([

+ 9 - 5
extension/core/bg/config.js

@@ -21,7 +21,7 @@
  *   Source.
  */
 
-/* global browser, singlefile, URL, Blob */
+/* global browser, singlefile, navigator, URL, Blob */
 
 singlefile.extension.core.bg.config = (() => {
 
@@ -75,6 +75,7 @@ singlefile.extension.core.bg.config = (() => {
 		DEFAULT_PROFILE_NAME,
 		DISABLED_PROFILE_NAME,
 		CURRENT_PROFILE_NAME,
+		get: getConfig,
 		getRule,
 		getOptions,
 		getProfiles,
@@ -101,6 +102,9 @@ singlefile.extension.core.bg.config = (() => {
 			await browser.storage.local.remove(["profiles", "defaultProfile", "rules"]);
 			await browser.storage.local.set({ profiles: config.profiles, rules: config.rules });
 		}
+		if (!config.maxParallelWorkers) {
+			await browser.storage.local.set({ maxParallelWorkers: navigator.hardwareConcurrency || 4 });
+		}
 	}
 
 	function applyUpgrade(config) {
@@ -133,7 +137,7 @@ singlefile.extension.core.bg.config = (() => {
 
 	async function getConfig() {
 		await pendingUpgradePromise;
-		return browser.storage.local.get(["profiles", "rules"]);
+		return browser.storage.local.get(["profiles", "rules", "maxParallelWorkers"]);
 	}
 
 	function sortRules(ruleLeft, ruleRight) {
@@ -360,7 +364,7 @@ singlefile.extension.core.bg.config = (() => {
 
 	async function exportConfig() {
 		const config = await getConfig();
-		const url = URL.createObjectURL(new Blob([JSON.stringify({ profiles: config.profiles, rules: config.rules }, null, 2)], { type: "text/json" }));
+		const url = URL.createObjectURL(new Blob([JSON.stringify({ profiles: config.profiles, rules: config.rules, maxParallelWorkers: config.maxParallelWorkers }, null, 2)], { type: "text/json" }));
 		const downloadInfo = {
 			url,
 			filename: "singlefile-settings.json",
@@ -403,8 +407,8 @@ singlefile.extension.core.bg.config = (() => {
 	}
 
 	async function importConfig(config) {
-		await browser.storage.local.remove(["profiles", "rules"]);
-		await browser.storage.local.set({ profiles: config.profiles, rules: config.rules });
+		await browser.storage.local.remove(["profiles", "rules", "maxParallelWorkers"]);
+		await browser.storage.local.set({ profiles: config.profiles, rules: config.rules, maxParallelWorkers: config.maxParallelWorkers });
 		await upgrade();
 	}