From 2d1e4e20e6c8b265c652ef73e66c3ccb1a90c4a1 Mon Sep 17 00:00:00 2001 From: xieshuang Date: Thu, 14 Nov 2024 16:54:49 +0800 Subject: [PATCH] fix: add patch lockfile for multiple instances (#500) add lockfile for multiple instances (#495) --- src/background/Background.ts | 7 ++--- src/background/CssFile.ts | 8 ++--- src/background/PatchFile/PatchFile.base.ts | 20 +++++++----- .../PatchFile/PatchFile.javascript.ts | 31 +++++++++++++------ .../PatchGenerator/PatchGenerator.base.ts | 4 +-- src/background/PatchGenerator/index.ts | 4 +-- src/utils/index.ts | 6 ++-- src/utils/vscodePath.ts | 6 ++-- 8 files changed, 51 insertions(+), 35 deletions(-) diff --git a/src/background/Background.ts b/src/background/Background.ts index cfca171..946d008 100644 --- a/src/background/Background.ts +++ b/src/background/Background.ts @@ -4,7 +4,6 @@ import path from 'path'; import vscode, { Disposable, l10n, Uri } from 'vscode'; -import { utils } from '../utils'; import { ENCODING, EXTENSION_NAME, TOUCH_JSFILE_PATH, VERSION } from '../utils/constants'; import { vscodePath } from '../utils/vscodePath'; import { vsHelp } from '../utils/vsHelp'; @@ -19,6 +18,7 @@ type TConfigType = vscode.WorkspaceConfiguration & TPatchGeneratorConfig; /** * 插件逻辑类 + * Extension logic * * @export * @class Background @@ -36,6 +36,7 @@ export class Background implements Disposable { public jsFile = new JsPatchFile(vscodePath.jsPath); /** + * Current config * 当前用户配置 * * @private @@ -220,10 +221,6 @@ export class Background implements Disposable { return; } - // 50~550ms 的延时,对于可能的多实例,错开对于文件的操作 - // 虽然有锁了,但这样更安心 =。= - await utils.sleep(50 + ~~(Math.random() * 500)); - this.onConfigChange(); }) ); diff --git a/src/background/CssFile.ts b/src/background/CssFile.ts index c156aa2..7f04138 100644 --- a/src/background/CssFile.ts +++ b/src/background/CssFile.ts @@ -8,7 +8,7 @@ import fs, { constants as fsConstants } from 'fs'; import { tmpdir } from 'os'; import path from 'path'; -import { utils } from '../utils'; +import { _ } from '../utils'; import { BACKGROUND_VER, ENCODING, VERSION } from '../utils/constants'; import { vsc } from '../utils/vsc'; @@ -116,7 +116,7 @@ export class CssFile { try { const mvcmd = process.platform === 'win32' ? 'move /Y' : 'mv -f'; const cmdarg = `${mvcmd} "${tempFilePath}" "${this.filePath}"`; - await utils.sudoExec(cmdarg, { name: 'Visual Studio Code Background Extension' }); + await _.sudoExec(cmdarg, { name: 'Visual Studio Code Background Extension' }); return true; } catch (e: any) { await vsc.window.showErrorMessage(e.message); @@ -177,7 +177,7 @@ export class CssFile { */ public async uninstall(): Promise { try { - await utils.lock(); + await _.lock(); let content = await this.getContent(); content = this.clearContent(content); // 异常case return @@ -189,7 +189,7 @@ export class CssFile { console.log(ex); return false; } finally { - await utils.unlock(); + await _.unlock(); } } } diff --git a/src/background/PatchFile/PatchFile.base.ts b/src/background/PatchFile/PatchFile.base.ts index 246d642..50e6206 100644 --- a/src/background/PatchFile/PatchFile.base.ts +++ b/src/background/PatchFile/PatchFile.base.ts @@ -3,7 +3,7 @@ import fs, { constants as fsConstants } from 'fs'; import { tmpdir } from 'os'; import path from 'path'; -import { utils } from '../../utils'; +import { _ } from '../../utils'; import { BACKGROUND_VER, ENCODING, VERSION } from '../../utils/constants'; import { vsc } from '../../utils/vsc'; @@ -96,7 +96,7 @@ export abstract class AbsPatchFile { try { const mvcmd = process.platform === 'win32' ? 'move /Y' : 'mv -f'; const cmdarg = `${mvcmd} "${tempFilePath}" "${filePath}"`; - await utils.sudoExec(cmdarg, { name: 'Background Extension' }); + await _.sudoExec(cmdarg, { name: 'Background Extension' }); return true; } catch (e: any) { vsc.window.showErrorMessage(e.message, { title: 'Common Issue' }).then(confirm => { @@ -145,11 +145,15 @@ export abstract class AbsPatchFile { protected abstract cleanPatches(content: string): string; public async restore() { - await utils.lock(); - let content = await this.getContent(); - content = this.cleanPatches(content); - const ok = await this.write(content); - await utils.unlock(); - return ok; + try { + await _.lock(); + let content = await this.getContent(); + content = this.cleanPatches(content); + return await this.write(content); + } catch { + return false; + } finally { + await _.unlock(); + } } } diff --git a/src/background/PatchFile/PatchFile.javascript.ts b/src/background/PatchFile/PatchFile.javascript.ts index d4f07f0..c6cb7f9 100644 --- a/src/background/PatchFile/PatchFile.javascript.ts +++ b/src/background/PatchFile/PatchFile.javascript.ts @@ -1,3 +1,4 @@ +import { _ } from '../../utils'; import { BACKGROUND_VER, VERSION } from '../../utils/constants'; import { AbsPatchFile } from './PatchFile.base'; @@ -13,16 +14,28 @@ import { AbsPatchFile } from './PatchFile.base'; */ export class JsPatchFile extends AbsPatchFile { public async applyPatches(patchContent: string): Promise { - let content = await this.getContent(); - content = this.cleanPatches(content); - content += [ - // - `\n// vscode-background-start ${BACKGROUND_VER}.${VERSION}`, - patchContent, - '// vscode-background-end' - ].join('\n'); + try { + await _.lock(); + const curContent = await this.getContent(); + let content = this.cleanPatches(curContent); + content += [ + // + `\n// vscode-background-start ${BACKGROUND_VER}.${VERSION}`, + patchContent, + '// vscode-background-end' + ].join('\n'); - return this.write(content); + // file unchanged + if (curContent === content) { + return true; + } + + return await this.write(content); + } catch { + return false; + } finally { + await _.unlock(); + } } protected cleanPatches(content: string): string { diff --git a/src/background/PatchGenerator/PatchGenerator.base.ts b/src/background/PatchGenerator/PatchGenerator.base.ts index 2867b88..527a0de 100644 --- a/src/background/PatchGenerator/PatchGenerator.base.ts +++ b/src/background/PatchGenerator/PatchGenerator.base.ts @@ -1,7 +1,7 @@ import * as stylis from 'stylis'; import vscode from 'vscode'; -import { utils } from '../../utils'; +import { _ } from '../../utils'; /** * 用于触发开发工具 css in js 语言支持 @@ -126,7 +126,7 @@ container.appendChild(div); script ] .filter(n => !!n.length) - .map(n => utils.withIIFE(n)) + .map(n => _.withIIFE(n)) .join(';'); } } diff --git a/src/background/PatchGenerator/index.ts b/src/background/PatchGenerator/index.ts index 5402630..c485d1a 100644 --- a/src/background/PatchGenerator/index.ts +++ b/src/background/PatchGenerator/index.ts @@ -1,6 +1,6 @@ import uglifyjs from 'uglify-js'; -import { utils } from '../../utils'; +import { _ } from '../../utils'; import { ChecksumsPatchGenerator } from './PatchGenerator.checksums'; import { EditorPatchGenerator, @@ -28,7 +28,7 @@ export class PatchGenerator { new PanelPatchGenerator(options.panel).create(), // panel new FullscreenPatchGenerator(options.fullscreen).create() // fullscreen ] - .map(n => utils.withIIFE(n)) + .map(n => _.withIIFE(n)) .join(';'); // return script; diff --git a/src/utils/index.ts b/src/utils/index.ts index 5ce3fad..d923b66 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -4,7 +4,7 @@ import lockfile from 'lockfile'; import { LOCK_PATH } from './constants'; import { vsc } from './vsc'; -export namespace utils { +export namespace _ { /** * if zh-CN */ @@ -43,7 +43,9 @@ export namespace utils { lockfile.lock( LOCK_PATH, { - wait: 5000 // 应该能撑200的并发了,,,>_<#@! + // When multiple VSCode instances are running, all instances' commands need to be executed within the `wait` time + // 在打开了多个vscode实例时,需要所有实例的命令在`wait`时间内执行完毕 + wait: 1000 * 30 }, err => { if (err) { diff --git a/src/utils/vscodePath.ts b/src/utils/vscodePath.ts index eb8e8c6..8dd7ab0 100644 --- a/src/utils/vscodePath.ts +++ b/src/utils/vscodePath.ts @@ -1,6 +1,6 @@ import path from 'path'; -import { utils } from './index'; +import { _ } from './index'; import { vsc } from './vsc'; // 基础目录 @@ -18,7 +18,7 @@ const cssPath = (() => { // https://github.com/microsoft/vscode/pull/141263 const webPath = getCssPath('workbench.web.main.css'); - if (utils.isDesktop) { + if (_.isDesktop) { return defPath; } return webPath; @@ -29,7 +29,7 @@ const jsPath = (() => { // desktop // /Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/workbench/workbench.desktop.main.js - if (utils.isDesktop) { + if (_.isDesktop) { return path.join(base, 'vs/workbench/workbench.desktop.main.js'); }