diff --git "a/docs/res/\350\265\267\345\213\225\343\202\267\343\203\274\343\202\261\343\203\263\343\202\271\345\233\263.md" "b/docs/res/\350\265\267\345\213\225\343\202\267\343\203\274\343\202\261\343\203\263\343\202\271\345\233\263.md" index bfcc705466..331acd8112 100644 --- "a/docs/res/\350\265\267\345\213\225\343\202\267\343\203\274\343\202\261\343\203\263\343\202\271\345\233\263.md" +++ "b/docs/res/\350\265\267\345\213\225\343\202\267\343\203\274\343\202\261\343\203\263\343\202\271\345\233\263.md" @@ -25,7 +25,7 @@ flowchart 870482["store.get registeredEngineDirs"] --> 250263 222321 --> 967432["engine.runEngineAll"] 656570["engine.fetchEngineInfos"] --> 870482 - 110954["engine.initializeEngineInfosAndAltPortInfo"] --> 656570 + 110954["engine.initializeAltPortInfo"] --> 656570 967432 --> 302398["runtimeInfo.setEngineInfos"] 302398 --> 321984 subgraph 656570["engine.fetchEngineInfos"] diff --git a/src/backend/electron/engineAndVvppController.ts b/src/backend/electron/engineAndVvppController.ts index 4f5e68f65e..8b6d1108b3 100644 --- a/src/backend/electron/engineAndVvppController.ts +++ b/src/backend/electron/engineAndVvppController.ts @@ -132,8 +132,8 @@ export class EngineAndVvppController { // エンジンの準備と起動 async launchEngines() { - // エンジンの追加と削除を反映させるためEngineInfoとAltPortInfosを再生成する。 - this.engineInfoManager.initializeEngineInfosAndAltPortInfo(); + // AltPortInfosを再生成する。 + this.engineInfoManager.initializeAltPortInfo(); // TODO: デフォルトエンジンの処理をConfigManagerに移してブラウザ版と共通化する const engineInfos = this.engineInfoManager.fetchEngineInfos(); diff --git a/src/backend/electron/manager/engineInfoManager.ts b/src/backend/electron/manager/engineInfoManager.ts index e219797f12..51f8f557f9 100644 --- a/src/backend/electron/manager/engineInfoManager.ts +++ b/src/backend/electron/manager/engineInfoManager.ts @@ -18,9 +18,9 @@ import { AltPortInfos } from "@/store/type"; import { BaseConfigManager } from "@/backend/common/ConfigManager"; /** - * デフォルトエンジンの情報を作成する + * デフォルトエンジンの情報を取得する */ -function createDefaultEngineInfos(defaultEngineDir: string): EngineInfo[] { +function fetchDefaultEngineInfos(defaultEngineDir: string): EngineInfo[] { // TODO: envから直接ではなく、envに書いたengine_manifest.jsonから情報を得るようにする const defaultEngineInfosEnv = import.meta.env.VITE_DEFAULT_ENGINE_INFOS ?? "[]"; @@ -48,9 +48,6 @@ export class EngineInfoManager { defaultEngineDir: string; vvppEngineDir: string; - defaultEngineInfos: EngineInfo[] = []; - additionalEngineInfos: EngineInfo[] = []; - /** 代替ポート情報 */ public altPortInfos: AltPortInfos = {}; @@ -65,10 +62,10 @@ export class EngineInfoManager { } /** - * 追加エンジンの一覧を作成する。 + * 追加エンジンの一覧を取得する。 * FIXME: store.get("registeredEngineDirs")への副作用をEngineManager外に移動する */ - private createAdditionalEngineInfos(): EngineInfo[] { + private fetchAdditionalEngineInfos(): EngineInfo[] { const engines: EngineInfo[] = []; const addEngine = (engineDir: string, type: "vvpp" | "path") => { const manifestPath = path.join(engineDir, "engine_manifest.json"); @@ -139,7 +136,20 @@ export class EngineInfoManager { * 全てのエンジンの一覧を取得する。デフォルトエンジン+追加エンジン。 */ fetchEngineInfos(): EngineInfo[] { - return [...this.defaultEngineInfos, ...this.additionalEngineInfos]; + const engineInfos = [ + ...fetchDefaultEngineInfos(this.defaultEngineDir), + ...this.fetchAdditionalEngineInfos(), + ]; + // 代替ポートに置き換える + engineInfos.forEach((engineInfo) => { + const altPortInfo = this.altPortInfos[engineInfo.uuid]; + if (altPortInfo) { + const url = new URL(engineInfo.host); + url.port = altPortInfo.to.toString(); + engineInfo.host = url.origin; + } + }); + return engineInfos; } /** @@ -170,11 +180,9 @@ export class EngineInfoManager { } /** - * EngineInfosとAltPortInfoを初期化する。 + * AltPortInfoを初期化する。 */ - initializeEngineInfosAndAltPortInfo() { - this.defaultEngineInfos = createDefaultEngineInfos(this.defaultEngineDir); - this.additionalEngineInfos = this.createAdditionalEngineInfos(); + initializeAltPortInfo() { this.altPortInfos = {}; } @@ -189,9 +197,6 @@ export class EngineInfoManager { from: Number(url.port), to: port, }; - - url.port = port.toString(); - engineInfo.host = url.toString(); } /** diff --git a/src/backend/electron/manager/engineProcessManager.ts b/src/backend/electron/manager/engineProcessManager.ts index 539676f2b8..2e0294cef3 100644 --- a/src/backend/electron/manager/engineProcessManager.ts +++ b/src/backend/electron/manager/engineProcessManager.ts @@ -88,39 +88,34 @@ export class EngineProcessManager { // { hostname (localhost), port (50021) } <- url (http://localhost:50021) const engineHostInfo = url2HostInfo(new URL(engineInfo.host)); + // ポートが塞がっていれば代替ポートを探す + let port = engineHostInfo.port; log.info( - `ENGINE ${engineId}: Checking whether port ${engineHostInfo.port} is assignable...`, + `ENGINE ${engineId}: Checking whether port ${port} is assignable...`, ); - if ( - !(await isAssignablePort(engineHostInfo.port, engineHostInfo.hostname)) - ) { + if (!(await isAssignablePort(port, engineHostInfo.hostname))) { // ポートを既に割り当てているプロセスidの取得 const pid = await getPidFromPort(engineHostInfo); if (pid != undefined) { const processName = await getProcessNameFromPid(engineHostInfo, pid); log.warn( - `ENGINE ${engineId}: Port ${engineHostInfo.port} has already been assigned by ${processName} (pid=${pid})`, + `ENGINE ${engineId}: Port ${port} has already been assigned by ${processName} (pid=${pid})`, ); } else { // ポートは使用不可能だがプロセスidは見つからなかった - log.warn( - `ENGINE ${engineId}: Port ${engineHostInfo.port} was unavailable`, - ); + log.warn(`ENGINE ${engineId}: Port ${port} was unavailable`); } // 代替ポートの検索 - const altPort = await findAltPort( - engineHostInfo.port, - engineHostInfo.hostname, - ); + const altPort = await findAltPort(port, engineHostInfo.hostname); // 代替ポートが見つからないとき if (altPort == undefined) { log.error(`ENGINE ${engineId}: No Alternative Port Found`); dialog.showErrorBox( `${engineInfo.name} の起動に失敗しました`, - `${engineHostInfo.port}番ポートの代わりに利用可能なポートが見つかりませんでした。PCを再起動してください。`, + `${port}番ポートの代わりに利用可能なポートが見つかりませんでした。PCを再起動してください。`, ); app.exit(1); throw new Error("No Alternative Port Found"); @@ -129,8 +124,10 @@ export class EngineProcessManager { // 代替ポート情報を更新 this.engineAltPortUpdater(engineId, altPort); log.warn( - `ENGINE ${engineId}: Applied Alternative Port: ${engineHostInfo.port} -> ${altPort}`, + `ENGINE ${engineId}: Applied Alternative Port: ${port} -> ${altPort}`, ); + + port = altPort; } log.info(`ENGINE ${engineId}: Starting process`); @@ -157,7 +154,7 @@ export class EngineProcessManager { "--host", new URL(engineInfo.host).hostname, "--port", - new URL(engineInfo.host).port, + port.toString(), ]); log.info(`ENGINE ${engineId} path: ${enginePath}`); diff --git a/src/type/preload.ts b/src/type/preload.ts index e55097f554..64dd56546c 100644 --- a/src/type/preload.ts +++ b/src/type/preload.ts @@ -402,7 +402,7 @@ export type MinimumEngineManifestType = z.infer< export type EngineInfo = { uuid: EngineId; - host: string; + host: string; // NOTE: 実際はorigin(プロトコルとhostnameとport)が入る name: string; path?: string; // エンジンディレクトリのパス executionEnabled: boolean;