Просмотр исходного кода

fixed pending saves issue

Former-commit-id: c2bceb36a0e82a55171d5e81488213244bab50ad
Gildas 6 лет назад
Родитель
Сommit
1fafa9ac5a
1 измененных файлов с 52 добавлено и 53 удалено
  1. 52 53
      extension/core/bg/business.js

+ 52 - 53
extension/core/bg/business.js

@@ -70,57 +70,67 @@ singlefile.extension.core.bg.business = (() => {
 	};
 	};
 
 
 	async function saveTabs(tabs, options = {}) {
 	async function saveTabs(tabs, options = {}) {
-		if (tabs.length) {
+		for (const tab of tabs) {
 			const config = singlefile.extension.core.bg.config;
 			const config = singlefile.extension.core.bg.config;
 			const autosave = singlefile.extension.core.bg.autosave;
 			const autosave = singlefile.extension.core.bg.autosave;
 			const ui = singlefile.extension.ui.bg.main;
 			const ui = singlefile.extension.ui.bg.main;
 			maxParallelWorkers = (await config.get()).maxParallelWorkers;
 			maxParallelWorkers = (await config.get()).maxParallelWorkers;
-			const tab = tabs.shift();
 			const tabId = tab.id;
 			const tabId = tab.id;
-			options.tabId = tabId;
-			options.tabIndex = tab.index;
-			try {
-				if (options.autoSave) {
-					const tabOptions = await config.getOptions(tab.url, true);
-					if (autosave.isEnabled(tab)) {
-						await requestSaveTab(tab, "content.autosave", tabOptions);
-					}
-				} else {
-					ui.onStart(tabId, INJECT_SCRIPTS_STEP);
-					const tabOptions = await config.getOptions(tab.url);
-					Object.keys(options).forEach(key => tabOptions[key] = options[key]);
-					tabOptions.extensionScriptFiles = extensionScriptFiles;
-					const scriptsInjected = await singlefile.extension.injectScript(tabId, tabOptions);
-					let promiseSaveTab;
-					if (scriptsInjected) {
-						ui.onStart(tabId, EXECUTE_SCRIPTS_STEP);
-						promiseSaveTab = requestSaveTab(tab, "content.save", tabOptions);
-					} else {
-						ui.onForbiddenDomain(tab);
-						promiseSaveTab = Promise.resolve();
-					}
-					saveTabs(tabs, options);
-					const saveInfo = pendingSaves.get(tabId);
-					await promiseSaveTab;
-					if (tabOptions.autoClose && saveInfo && !saveInfo.cancelled) {
-						singlefile.extension.core.bg.tabs.remove(tabId);
-					}
-				}
-			} catch (error) {
-				if (error && (!error.message || (error.message != ERROR_CONNECTION_LOST_CHROMIUM && error.message != ERROR_CONNECTION_ERROR_CHROMIUM && error.message != ERROR_CONNECTION_LOST_GECKO))) {
-					console.log(error); // eslint-disable-line no-console
-					ui.onError(tabId);
+			const tabOptions = await config.getOptions(tab.url);
+			Object.keys(options).forEach(key => tabOptions[key] = options[key]);
+			tabOptions.tabId = tabId;
+			tabOptions.tabIndex = tab.index;
+			tabOptions.extensionScriptFiles = extensionScriptFiles;
+			if (options.autoSave) {
+				if (autosave.isEnabled(tab)) {
+					pendingSaves.set(tab.id, { status: "pending", tab, options: tabOptions, method: "content.autosave" });
 				}
 				}
-			} finally {
-				pendingSaves.delete(tabId);
-				const nextPendingSave = Array.from(pendingSaves).filter(([, saveInfo]) => saveInfo.status == "pending");
-				if (nextPendingSave.length) {
-					const [tabId, { tab, method, resolve, reject, options }] = nextPendingSave[0];
-					pendingSaves.delete(tabId);
-					requestSaveTab(tab, method, options, resolve, reject);
+			} else {
+				ui.onStart(tabId, INJECT_SCRIPTS_STEP);
+				const scriptsInjected = await singlefile.extension.injectScript(tabId, tabOptions);
+				if (scriptsInjected) {
+					ui.onStart(tabId, EXECUTE_SCRIPTS_STEP);
+					pendingSaves.set(tab.id, { status: "pending", tab, options: tabOptions, method: "content.save" });
+				} else {
+					ui.onForbiddenDomain(tab);
 				}
 				}
 			}
 			}
 		}
 		}
+		const processingCount = Array.from(pendingSaves).filter(([, saveInfo]) => saveInfo.status == "processing").length;
+		for (let index = 0; index < Math.min(tabs.length, (maxParallelWorkers - processingCount)); index++) {
+			runTask();
+		}
+
+		function runTask() {
+			const nextPendingSave = Array.from(pendingSaves).find(([, saveInfo]) => saveInfo.status == "pending");
+			if (nextPendingSave) {
+				const [tabId, saveInfo] = nextPendingSave;
+				return new Promise((resolve, reject) => {
+					saveInfo.status = "processing";
+					saveInfo.resolve = async () => {
+						if (saveInfo.options.autoClose && !saveInfo.cancelled) {
+							singlefile.extension.core.bg.tabs.remove(tabId);
+						}
+						pendingSaves.delete(tabId);
+						resolve();
+						await runTask();
+					};
+					saveInfo.reject = async error => {
+						pendingSaves.delete(tabId);
+						reject(error);
+						await runTask();
+					};
+					singlefile.extension.core.bg.tabs.sendMessage(tabId, { method: saveInfo.method, options: saveInfo.options })
+						.catch(error => {
+							if (error && (!error.message || (error.message != ERROR_CONNECTION_LOST_CHROMIUM && error.message != ERROR_CONNECTION_ERROR_CHROMIUM && error.message != ERROR_CONNECTION_LOST_GECKO))) {
+								console.log(error); // eslint-disable-line no-console
+								singlefile.extension.ui.bg.main.onError(tabId);
+								saveInfo.reject(error);
+							}
+						});
+				});
+			}
+		}
 	}
 	}
 
 
 	async function saveLink(url, options = {}) {
 	async function saveLink(url, options = {}) {
@@ -147,17 +157,6 @@ singlefile.extension.core.bg.business = (() => {
 		}
 		}
 	}
 	}
 
 
-	function requestSaveTab(tab, method, options) {
-		return new Promise((resolve, reject) => {
-			if (Array.from(pendingSaves).filter(([, saveInfo]) => saveInfo.status == "processing").length < maxParallelWorkers) {
-				pendingSaves.set(tab.id, { status: "processing", tab, options, method, resolve, reject });
-				singlefile.extension.core.bg.tabs.sendMessage(tab.id, { method, options });
-			} else {
-				pendingSaves.set(tab.id, { status: "pending", tab, options, method, resolve, reject });
-			}
-		});
-	}
-
 	function mapSaveInfo([tabId, saveInfo]) {
 	function mapSaveInfo([tabId, saveInfo]) {
 		return [tabId, { index: saveInfo.tab.index, url: saveInfo.tab.url, title: saveInfo.tab.title, cancelled: saveInfo.cancelled, status: saveInfo.status }];
 		return [tabId, { index: saveInfo.tab.index, url: saveInfo.tab.url, title: saveInfo.tab.title, cancelled: saveInfo.cancelled, status: saveInfo.status }];
 	}
 	}