diff --git a/vscode-extension/package.json b/vscode-extension/package.json index fe4a1154b..1098e00b0 100644 --- a/vscode-extension/package.json +++ b/vscode-extension/package.json @@ -179,6 +179,7 @@ }, "dependencies": { "@vscode/python-extension": "^1.0.5", + "async-mutex": "^0.4.1", "oboe": "^2.1.5", "portfinder": "^1.0.32", "ufetch": "^1.6.0" @@ -186,4 +187,4 @@ "extensionDependencies": [ "ms-python.python" ] -} \ No newline at end of file +} diff --git a/vscode-extension/src/aiConfigEditor.ts b/vscode-extension/src/aiConfigEditor.ts index 924324da7..1d4cf140a 100644 --- a/vscode-extension/src/aiConfigEditor.ts +++ b/vscode-extension/src/aiConfigEditor.ts @@ -15,7 +15,7 @@ import { AIConfigEditorManager, AIConfigEditorState, } from "./aiConfigEditorManager"; -import { EditorServer, EditorServerState } from "./editorServer"; +import { EditorServer, EditorServerState } from "./editor_server/editorServer"; /** * Provider for AIConfig editors. diff --git a/vscode-extension/src/aiConfigEditorManager.ts b/vscode-extension/src/aiConfigEditorManager.ts index 11b872eb6..aedd8a892 100644 --- a/vscode-extension/src/aiConfigEditorManager.ts +++ b/vscode-extension/src/aiConfigEditorManager.ts @@ -1,5 +1,5 @@ import vscode from "vscode"; -import { EditorServer } from "./editorServer"; +import { EditorServer } from "./editor_server/editorServer"; export class AIConfigEditorState { constructor( diff --git a/vscode-extension/src/editorServer.ts b/vscode-extension/src/editor_server/editorServer.ts similarity index 95% rename from vscode-extension/src/editorServer.ts rename to vscode-extension/src/editor_server/editorServer.ts index d618041c2..c548d9898 100644 --- a/vscode-extension/src/editorServer.ts +++ b/vscode-extension/src/editor_server/editorServer.ts @@ -1,8 +1,8 @@ import * as vscode from "vscode"; -import { getPortPromise } from "portfinder"; -import { EXTENSION_NAME } from "./util"; -import { getPythonPath } from "./utilities/pythonSetupUtils"; +import { EXTENSION_NAME } from "../util"; +import { getPythonPath } from "../utilities/pythonSetupUtils"; import { ChildProcessWithoutNullStreams, spawn } from "child_process"; +import serverPortManager from "./serverPortManager"; export enum EditorServerState { Starting = "Starting", @@ -74,7 +74,7 @@ export class EditorServer { ? ["--parsers-module-path", modelRegistryPath] : []; - this.port = await getPortPromise(); + this.port = await serverPortManager.getPort(); const pythonPath = await getPythonPath(); diff --git a/vscode-extension/src/editor_server/serverPortManager.ts b/vscode-extension/src/editor_server/serverPortManager.ts new file mode 100644 index 000000000..6ce8a2eed --- /dev/null +++ b/vscode-extension/src/editor_server/serverPortManager.ts @@ -0,0 +1,25 @@ +import { Mutex } from "async-mutex"; +import { getPortPromise } from "portfinder"; + +/** + * Super simple class to manage server port allocation using a lock mechanism. If + * we don't do this, restarting multiple servers simultaneously can result in + * obtaining the same port for multiple servers. + */ +class ServerPortManager { + private lock; + + constructor() { + this.lock = new Mutex(); + } + + async getPort(): Promise { + const release = await this.lock.acquire(); + const port = await getPortPromise(); + release(); + return port; + } +} + +const serverPortManager = new ServerPortManager(); +export default serverPortManager; diff --git a/vscode-extension/src/extension.ts b/vscode-extension/src/extension.ts index 86dfede68..859e9bb6f 100644 --- a/vscode-extension/src/extension.ts +++ b/vscode-extension/src/extension.ts @@ -182,8 +182,7 @@ export async function activate(context: vscode.ExtensionContext) { .then((selection) => { if (selection === "Yes") { editors.forEach((editor) => { - // Next PR: refresh editor here - vscode.window.showInformationMessage("Refresh boiiiiii"); + editor.editorServer.restart(); }); } }); diff --git a/vscode-extension/yarn.lock b/vscode-extension/yarn.lock index 788e06807..65e78c61e 100644 --- a/vscode-extension/yarn.lock +++ b/vscode-extension/yarn.lock @@ -338,6 +338,13 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== +async-mutex@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.4.1.tgz#bccf55b96f2baf8df90ed798cb5544a1f6ee4c2c" + integrity sha512-WfoBo4E/TbCX1G95XTjbWTE3X2XLG0m1Xbv2cwOtuPdyH9CZvnaA5nCt1ucjaKEgW2A5IF71hxrRhr83Je5xjA== + dependencies: + tslib "^2.4.0" + async@^2.6.4: version "2.6.4" resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" @@ -1458,6 +1465,11 @@ ts-api-utils@^1.0.1: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== +tslib@^2.4.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"