From 98f9c95145712166f7f8395a98337d0fa8803ca4 Mon Sep 17 00:00:00 2001 From: wappon-28-dev Date: Thu, 18 May 2023 22:33:50 +0900 Subject: [PATCH 01/12] =?UTF-8?q?Fix:=20PortManager=20=E3=82=92=E6=95=B4?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/background/engineManager.ts | 40 +++-- src/background/portManager.ts | 302 +++++++++++++++++++------------- 2 files changed, 199 insertions(+), 143 deletions(-) diff --git a/src/background/engineManager.ts b/src/background/engineManager.ts index 9ac0cb9fee..7679da4bdb 100644 --- a/src/background/engineManager.ts +++ b/src/background/engineManager.ts @@ -9,7 +9,12 @@ import { app, BrowserWindow, dialog } from "electron"; import log from "electron-log"; import { z } from "zod"; -import { PortManager } from "./portManager"; +import { + findAltPort, + getPidFromPort, + getProcessNameFromPid, + url2HostInfo, +} from "./portManager"; import { ipcMainSend } from "@/electron/ipc"; import { @@ -229,33 +234,30 @@ export class EngineManager { return; } - const engineInfoUrl = new URL(engineInfo.host); - const portManager = new PortManager( - engineInfoUrl.hostname, - parseInt(engineInfoUrl.port) - ); + // { hostname (localhost), port (50021) } <- url (http://localhost:50021) + const engineHostInfo = url2HostInfo(new URL(engineInfo.host)); log.info( - `ENGINE ${engineId}: Checking whether port ${engineInfoUrl.port} is assignable...` + `ENGINE ${engineId}: Checking whether port ${engineHostInfo.port} is assignable...` ); - // ポートを既に割り当てられているプロセスidの取得: undefined → ポートが空いている - const processId = await portManager.getProcessIdFromPort(); - if (processId !== undefined) { - const processName = await portManager.getProcessNameFromPid(processId); + // ポートを既に割り当てているプロセスidの取得: undefined → ポートが空いている + const pid = await getPidFromPort(engineHostInfo); + if (pid != null) { + const processName = await getProcessNameFromPid(engineHostInfo, pid); log.warn( - `ENGINE ${engineId}: Port ${engineInfoUrl.port} has already been assigned by ${processName} (pid=${processId})` + `ENGINE ${engineId}: Port ${engineHostInfo.port} has already been assigned by ${processName} (pid=${pid})` ); - // 代替ポート検索 - const altPort = await portManager.findAltPort(); + // 代替ポートの検索 + const altPort = await findAltPort(engineHostInfo); // 代替ポートが見つからないとき - if (!altPort) { + if (altPort == null) { log.error(`ENGINE ${engineId}: No Alternative Port Found`); dialog.showErrorBox( `${engineInfo.name} の起動に失敗しました`, - `${engineInfoUrl.port}番ポートの代わりに利用可能なポートが見つかりませんでした。PCを再起動してください。` + `${engineHostInfo.port}番ポートの代わりに利用可能なポートが見つかりませんでした。PCを再起動してください。` ); app.exit(1); throw new Error("No Alternative Port Found"); @@ -263,14 +265,14 @@ export class EngineManager { // 代替ポートの情報 this.altPortInfo[engineId] = { - from: parseInt(engineInfoUrl.port), + from: engineHostInfo.port, to: altPort, }; // 代替ポートを設定 - engineInfo.host = `http://${engineInfoUrl.hostname}:${altPort}`; + engineInfo.host = `http://${engineHostInfo.hostname}:${altPort}`; log.warn( - `ENGINE ${engineId}: Applied Alternative Port: ${engineInfoUrl.port} -> ${altPort}` + `ENGINE ${engineId}: Applied Alternative Port: ${engineHostInfo.port} -> ${altPort}` ); } diff --git a/src/background/portManager.ts b/src/background/portManager.ts index c1e2991148..4bf4db4134 100644 --- a/src/background/portManager.ts +++ b/src/background/portManager.ts @@ -3,146 +3,200 @@ import log from "electron-log"; const isWindows = process.platform === "win32"; -export class PortManager { - constructor(private hostname: string, private port: number) {} - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - portLog = (...message: any) => - log.info(`PORT ${this.port} (${this.hostname}): ${message}`); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - portWarn = (...message: any) => - log.warn(`PORT ${this.port} (${this.hostname}): ${message}`); - - /** - * "netstat -ano" の stdout から, 指定したポートを使用しているプロセスの process id を取得する - * - * ex) stdout: - * ``` cmd - * TCP 127.0.0.1:5173 127.0.0.1:50170 TIME_WAIT 0 - * TCP 127.0.0.1:6463 0.0.0.0:0 LISTENING 18692 - * TCP 127.0.0.1:50021 0.0.0.0:0 LISTENING 17320 - * ``` - * -> `17320` - * - * @param stdout netstat の stdout - * @returns `process id` or `undefined` (ポートが使用されていないとき) - */ - private stdout2processId(stdout: string): number | undefined { - const lines = stdout.split("\n"); - for (const line of lines) { - if (line.includes(`${this.hostname}:${this.port}`)) { - const parts = line.trim().split(/\s+/); - return parseInt(parts[parts.length - 1], 10); +type HostInfo = { + hostname: string; + port: number; +}; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const portLog = (port: number, message: string, isDeep = false) => + log.info(`${isDeep ? "| " : ""}PORT ${port}: ${message}`); +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const portWarn = (port: number, message: string, isDeep = false) => + log.warn(`${isDeep ? "| " : ""}PORT ${port}: ${message}`); + +function url2HostInfo(url: URL) { + return { + hostname: url.hostname, + port: Number(url.port), + }; +} + +/** + * "netstat -ano" の stdout から, 指定したポートを使用しているプロセスの process id を取得する. + * また, TCPの状態が TIME_WAIT のときはポートが割り当て可能だとみなします. + * + * ex) stdout: + * ``` cmd + * TCP 127.0.0.1:5173 127.0.0.1:50170 TIME_WAIT 0 + * TCP 127.0.0.1:6463 0.0.0.0:0 LISTENING 18692 + * TCP 127.0.0.1:50021 0.0.0.0:0 LISTENING 17320 + * ``` + * -> `17320` + * + * @param stdout netstat の stdout + * @param hostInfo ホスト情報 + * @returns `process id` or `undefined` (ポートが割り当て可能なとき) + */ +function netstatStdout2pid( + stdout: string, + hostInfo: HostInfo +): number | undefined { + const lines = stdout.split("\n"); + + for (const line of lines) { + if (line.includes(`${hostInfo.hostname}:${hostInfo.port}`)) { + const parts = line.trim().split(/\s+/); + const pid = parts[parts.length - 1]; + const tcpState = parts[parts.length - 2]; + + // 他のプロセスが割り当てをしているとみなすTCPの状態 + if (["LISTENING", "ESTABLISHED", "CLOSE_WAIT"].includes(tcpState)) { + return Number(pid); } } - return undefined; } - async getProcessIdFromPort(): Promise { - this.portLog("Getting process id..."); - const exec = isWindows - ? { - cmd: "netstat", - args: ["-ano"], - } - : { - cmd: "lsof", - args: ["-i", `:${this.port}`, "-t", "-sTCP:LISTEN"], - }; - - this.portLog(`Running command: "${exec.cmd} ${exec.args.join(" ")}"`); - - let stdout = execFileSync(exec.cmd, exec.args, { - shell: true, - }).toString(); - - if (isWindows) { - // Windows の場合は, lsof のように port と pid が 1to1 で取れないので, 3つのループバックアドレスが割り当てられているか確認 - const loopbackAddr = ["127.0.0.1", "0.0.0.0", "[::1]"]; - - // hostname が3つループバックアドレスのどれかの場合, それぞれのループバックアドレスに対して pid を取得 - if (loopbackAddr.includes(this.hostname)) { - this.portLog( - "Hostname is loopback address; Getting process id from all loopback addresses..." - ); + return undefined; +} - const pid: (number | undefined)[] = []; - loopbackAddr.forEach((hostname) => - pid.push( - // TODO: インスタンスの再定義を回避するなどのリファクタリング - new PortManager(hostname, this.port).stdout2processId(stdout) - ) +async function getPidFromPort( + hostInfo: HostInfo, + isDeep = false +): Promise { + // Windows の場合は, hostname が以下のループバックアドレスが割り当てられているか確認 + const parse4windows = (): string | undefined => { + // それぞれのループバックアドレスに対して pid を取得 + const loopbackAddr = ["localhost", "127.0.0.1", "0.0.0.0", "[::1]"]; + if (loopbackAddr.includes(hostInfo.hostname)) { + portLog( + hostInfo.port, + "Hostname is loopback address; Getting process id from all loopback addresses...", + isDeep + ); + + const pidArr: (number | undefined)[] = []; + loopbackAddr.forEach((hostname) => { + // netstat の stdout から pid を取得 + const pid = netstatStdout2pid(stdout, { + hostname, + port: hostInfo.port, + }); + + portLog( + hostInfo.port, + `| ${hostname}\t-> ${ + pid == null ? "Assignable" : `pid=${pid} uses this port` + }`, + isDeep ); - // pid が undefined (= 割り当て可能) でないものを取得 → 1つ目を取得 → stdoutへ - stdout = pid.filter((pid) => pid !== undefined)[0]?.toString() ?? ""; - } else { - stdout = this.stdout2processId(stdout)?.toString() ?? ""; - } - } + pidArr.push(pid); + }); - if (!stdout || !stdout.length) { - this.portLog("Assignable; Nobody uses this port!"); - return undefined; + // pid が undefined (= 割り当て可能) でないものを取得 → 1つ目を取得 + return pidArr.filter((pid) => pid !== undefined)[0]?.toString(); } + }; - this.portWarn(`Nonassignable; pid=${stdout} uses this port!`); - return parseInt(stdout); - } + portLog(hostInfo.port, "Getting process id...", isDeep); - async getProcessNameFromPid(pid: number): Promise { - this.portLog(`Getting process name from pid=${pid}...`); - const exec = isWindows - ? { - cmd: "wmic", - args: ["process", "where", `"ProcessID=${pid}"`, "get", "name"], - } - : { - cmd: "ps", - args: ["-p", pid.toString(), "-o", "comm="], - }; - - let stdout = execFileSync(exec.cmd, exec.args, { shell: true }).toString(); - - if (isWindows) { - /* - * ex) stdout: - * ``` - * Name - * node.exe - * ``` - * -> `node.exe` - */ - stdout = stdout.split("\r\n")[1]; - } - - this.portLog(`Found process name: ${stdout}`); - return stdout.trim(); + const exec = isWindows + ? { + cmd: "netstat", + args: ["-ano"], + } + : { + cmd: "lsof", + args: ["-i", `:${hostInfo.port}`, "-t", "-sTCP:LISTEN"], + }; + + portLog( + hostInfo.port, + `Running command: "${exec.cmd} ${exec.args.join(" ")}"...`, + isDeep + ); + + const stdout = execFileSync(exec.cmd, exec.args, { + shell: true, + }).toString(); + + // Windows の場合は, lsof のように port と pid が 1to1 で取れないので, netstat の stdout からパース + const pid = isWindows ? parse4windows() : stdout; + + if (pid == null || !pid.length) { + portLog(hostInfo.port, "Assignable; Nobody uses this port!", isDeep); + return undefined; } - /** - * 割り当て可能な他のポートを探します - * - * @returns 割り当て可能なポート番号 or `undefined` (割り当て可能なポートが見つからなかったとき) - */ - async findAltPort(): Promise { - this.portLog(`Find another assignable port from ${this.port}...`); + portWarn(hostInfo.port, `Nonassignable; pid=${pid} uses this port!`, isDeep); + return Number(pid); +} - // エンジン指定のポート + 100番までを探索 エフェメラルポートの範囲の最大は超えないようにする - const altPortMax = Math.min(this.port + 100, 65535); +async function getProcessNameFromPid( + hostInfo: HostInfo, + pid: number +): Promise { + portLog(hostInfo.port, `Getting process name from pid=${pid}...`); + const exec = isWindows + ? { + cmd: "wmic", + args: ["process", "where", `"ProcessID=${pid}"`, "get", "name"], + } + : { + cmd: "ps", + args: ["-p", pid.toString(), "-o", "comm="], + }; - for (let altPort = this.port + 1; altPort <= altPortMax; altPort++) { - this.portLog(`Trying whether port ${altPort} is assignable...`); - const altPid = await new PortManager( // TODO: インスタンスの再定義を回避するなどのリファクタリング - this.hostname, - altPort - ).getProcessIdFromPort(); + const stdout = execFileSync(exec.cmd, exec.args, { shell: true }).toString(); - // ポートを既に割り当てられているプロセスidの取得: undefined → ポートが空いている - if (altPid === undefined) return altPort; - } + /* + * ex) stdout: + * ``` + * Name + * node.exe + * ``` + * -> `node.exe` + */ + const processName = isWindows ? stdout.split("\n")[1] : stdout; - this.portWarn(`No alternative port found! ${this.port}...${altPortMax}`); - return undefined; + portLog(hostInfo.port, `Found process name: ${processName}`); + return processName.trim(); +} + +/** + * 割り当て可能な他のポートを探します + * + * @param hostInfo ホスト情報 + * @returns 割り当て可能なポート番号 or `undefined` (割り当て可能なポートが見つからなかったとき) + */ +async function findAltPort(hostInfo: HostInfo): Promise { + const basePort = hostInfo.port; + portLog(hostInfo.port, `Find another assignable port from ${basePort}...`); + + // エンジン指定のポート + 100番までを探索 エフェメラルポートの範囲の最大は超えないようにする + const altPortMax = Math.min(basePort + 100, 65535); + + for (let altPort = basePort + 1; altPort <= altPortMax; altPort++) { + portLog(hostInfo.port, `Trying whether port ${altPort} is assignable...`); + const altPid = await getPidFromPort( + { + hostname: hostInfo.hostname, + port: altPort, + }, + true + ); + + // ポートを既に割り当てられているプロセスidの取得: undefined → ポートが空いている + if (altPid == null) return altPort; } + + portWarn( + hostInfo.port, + `No alternative port found! ${basePort}...${altPortMax}` + ); + return undefined; } + +export type { HostInfo }; +export { url2HostInfo, getPidFromPort, getProcessNameFromPid, findAltPort }; From 552336276f4f9bc069d8d7650fd835724b48e75d Mon Sep 17 00:00:00 2001 From: wappon-28-dev Date: Fri, 19 May 2023 02:43:48 +0900 Subject: [PATCH 02/12] =?UTF-8?q?Add:=20state=E3=81=ABaltPortInfos?= =?UTF-8?q?=E3=82=92=E6=8C=81=E3=81=9F=E3=81=9B=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - トースト通知のタイミングも調整した - ウィンドウタイトルの値もwatchした --- src/components/MenuBar.vue | 25 +++++++---- src/store/engine.ts | 18 ++++++-- src/store/type.ts | 9 +++- src/views/EditorHome.vue | 79 +++++++++++++++++++++-------------- tests/unit/store/Vuex.spec.ts | 1 + 5 files changed, 89 insertions(+), 43 deletions(-) diff --git a/src/components/MenuBar.vue b/src/components/MenuBar.vue index 8c3d6d5a0a..ed4acf4362 100644 --- a/src/components/MenuBar.vue +++ b/src/components/MenuBar.vue @@ -70,13 +70,21 @@ export type MenuItemType = MenuItemData["type"]; const store = useStore(); const $q = useQuasar(); const currentVersion = ref(""); -const altPorts = ref([]); -store.dispatch("GET_ALT_PORT_INFOS").then( - (altPortInfo) => - // {[engineId]: {from: number, to: number}} -> to: number[] - (altPorts.value = Object.values(altPortInfo).map(({ to }) => to)) -); +// デフォルトエンジンの代替先ポート +const defaultEngineAltPortTo = computed(() => { + const altPortInfos = store.state.altPortInfos; + + // ref: https://github.com/VOICEVOX/voicevox/blob/32940eab36f4f729dd0390dca98f18656240d60d/src/views/EditorHome.vue#L522-L528 + const defaultEngineInfo = Object.values(store.state.engineInfos).find( + (engine) => engine.type === "default" + ); + if (defaultEngineInfo == null) return undefined; + + // : { from: number, to: number } -> to (代替先ポート) + return altPortInfos[defaultEngineInfo.uuid]?.to; +}); + window.electron.getAppInfos().then((obj) => { currentVersion.value = obj.version; }); @@ -100,8 +108,9 @@ const titleText = computed( "VOICEVOX" + (currentVersion.value ? " - Ver. " + currentVersion.value : "") + (isMultiEngineOffMode.value ? " - マルチエンジンオフ" : "") + - // メインエンジン (0番目) の代替ポートの表示のみ - (altPorts.value.length ? " - Port: " + altPorts.value[0] : "") + (defaultEngineAltPortTo.value != null + ? ` - Port: ${defaultEngineAltPortTo.value}` + : "") ); // FIXME: App.vue内に移動する diff --git a/src/store/engine.ts b/src/store/engine.ts index 803b8c9e6e..53e3e7c2a6 100644 --- a/src/store/engine.ts +++ b/src/store/engine.ts @@ -7,11 +7,12 @@ import type { EngineId, EngineInfo } from "@/type/preload"; export const engineStoreState: EngineStoreState = { engineStates: {}, engineSupportedDevices: {}, + altPortInfos: {}, }; export const engineStore = createPartialStore({ GET_ENGINE_INFOS: { - async action({ state, commit }) { + async action({ state, commit, dispatch }) { const engineInfos = await window.electron.engineInfos(); // マルチエンジンオフモード時はengineIdsをデフォルトエンジンのIDだけにする。 @@ -28,6 +29,9 @@ export const engineStore = createPartialStore({ engineIds, engineInfos, }); + + // 代替ポート情報を取得 → トースト通知が発火する + dispatch("GET_ALT_PORT_INFOS"); }, }, @@ -66,8 +70,16 @@ export const engineStore = createPartialStore({ }, GET_ALT_PORT_INFOS: { - async action() { - return await window.electron.getAltPortInfos(); + async action({ commit }) { + const altPortInfos = await window.electron.getAltPortInfos(); + commit("SET_ALT_PORT_INFOS", { altPortInfos }); + return altPortInfos; + }, + }, + + SET_ALT_PORT_INFOS: { + mutation(state, { altPortInfos }) { + state.altPortInfos = altPortInfos; }, }, diff --git a/src/store/type.ts b/src/store/type.ts index feba5eb2c2..5acdcdbb61 100644 --- a/src/store/type.ts +++ b/src/store/type.ts @@ -80,7 +80,9 @@ export type Command = { }; export type EngineState = "STARTING" | "FAILED_STARTING" | "ERROR" | "READY"; -export type AltPortInfos = Record; // ポートが塞がれていたときの代替ポート + +// ポートが塞がれていたときの代替ポート情報 +export type AltPortInfos = Record; export type SaveResult = | "SUCCESS" @@ -728,6 +730,7 @@ export type CommandStoreTypes = { export type EngineStoreState = { engineStates: Record; engineSupportedDevices: Record; + altPortInfos: AltPortInfos; }; export type EngineStoreTypes = { @@ -751,6 +754,10 @@ export type EngineStoreTypes = { action(): Promise; }; + SET_ALT_PORT_INFOS: { + mutation: { altPortInfos: AltPortInfos }; + }; + SET_ENGINE_MANIFESTS: { mutation: { engineManifests: Record }; }; diff --git a/src/views/EditorHome.vue b/src/views/EditorHome.vue index 480a6d2f23..1774f4390d 100644 --- a/src/views/EditorHome.vue +++ b/src/views/EditorHome.vue @@ -578,37 +578,8 @@ onMounted(async () => { isCompletedInitialStartup.value = true; - // 代替ポートをトースト通知する - // FIXME: トーストが何度も出るようにする(altPortInfoをstateに持たせてwatchする) - if (!store.state.confirmedTips.engineStartedOnAltPort) { - const altPortInfo = await store.dispatch("GET_ALT_PORT_INFOS"); - for (const engineId of store.state.engineIds) { - const engineName = store.state.engineInfos[engineId].name; - const altPort = altPortInfo[engineId]; - - if (!altPort) return; - $q.notify({ - message: `${altPort.from}番ポートが使用中であるため ${engineName} は、${altPort.to}番ポートで起動しました`, - color: "toast", - textColor: "toast-display", - icon: "compare_arrows", - timeout: 5000, - actions: [ - { - label: "今後この通知をしない", - textColor: "toast-button-display", - handler: () => - store.dispatch("SET_CONFIRMED_TIPS", { - confirmedTips: { - ...store.state.confirmedTips, - engineStartedOnAltPort: true, - }, - }), - }, - ], - }); - } - } + // 代替ポート情報を取得 → トースト通知が発火する + await store.dispatch("GET_ALT_PORT_INFOS"); }); // エンジン待機 @@ -651,6 +622,52 @@ watch(allEngineState, (newEngineState) => { isEngineWaitingLong.value = false; } }); + +// 代替ポート情報の変更を監視 +watch( + () => store.state.altPortInfos, + async (newAltPortInfos) => { + // この watch が, エンジンが起動した時 (=> 設定ファイルを読み込む前) に発火して + // "今後この通知をしない" を無視するのを防ぐために, 初期化処理 (=> 設定ファイルが読み込まれる) まで待つ + if (!isCompletedInitialStartup.value) return; + + // "今後この通知をしない" を考慮 + if (store.state.confirmedTips.engineStartedOnAltPort) return; + + // 代替ポートをトースト通知する + for (const engineId of store.state.engineIds) { + const engineName = store.state.engineInfos[engineId].name; + const altPort = newAltPortInfos[engineId]; + + console.log({ altPort }); + + if (!altPort) return; + + console.log("notices"); + $q.notify({ + message: `${altPort.from}番ポートが使用中であるため ${engineName} は、${altPort.to}番ポートで起動しました`, + color: "toast", + textColor: "toast-display", + icon: "compare_arrows", + timeout: 5000, + actions: [ + { + label: "今後この通知をしない", + textColor: "toast-button-display", + handler: () => + store.dispatch("SET_CONFIRMED_TIPS", { + confirmedTips: { + ...store.state.confirmedTips, + engineStartedOnAltPort: true, + }, + }), + }, + ], + }); + } + } +); + const restartAppWithMultiEngineOffMode = () => { store.dispatch("RESTART_APP", { isMultiEngineOffMode: true }); }; diff --git a/tests/unit/store/Vuex.spec.ts b/tests/unit/store/Vuex.spec.ts index 07e99ef11b..4ab6aaeb03 100644 --- a/tests/unit/store/Vuex.spec.ts +++ b/tests/unit/store/Vuex.spec.ts @@ -25,6 +25,7 @@ describe("store/vuex.js test", () => { [engineId]: "STARTING", }, engineSupportedDevices: {}, + altPortInfos: {}, characterInfos: {}, morphableTargetsInfo: {}, defaultStyleIds: [], From c2b9668972ed56ca0ce7bfa1d18e36389992ae14 Mon Sep 17 00:00:00 2001 From: wappon-28-dev Date: Fri, 19 May 2023 02:51:21 +0900 Subject: [PATCH 03/12] Fix: isDeep -> isNested --- src/background/portManager.ts | 26 +++++++++++++++----------- src/views/EditorHome.vue | 4 ---- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/background/portManager.ts b/src/background/portManager.ts index 4bf4db4134..254e11a74c 100644 --- a/src/background/portManager.ts +++ b/src/background/portManager.ts @@ -9,11 +9,11 @@ type HostInfo = { }; // eslint-disable-next-line @typescript-eslint/no-explicit-any -const portLog = (port: number, message: string, isDeep = false) => - log.info(`${isDeep ? "| " : ""}PORT ${port}: ${message}`); +const portLog = (port: number, message: string, isNested = false) => + log.info(`${isNested ? "| " : ""}PORT ${port}: ${message}`); // eslint-disable-next-line @typescript-eslint/no-explicit-any -const portWarn = (port: number, message: string, isDeep = false) => - log.warn(`${isDeep ? "| " : ""}PORT ${port}: ${message}`); +const portWarn = (port: number, message: string, isNested = false) => + log.warn(`${isNested ? "| " : ""}PORT ${port}: ${message}`); function url2HostInfo(url: URL) { return { @@ -62,7 +62,7 @@ function netstatStdout2pid( async function getPidFromPort( hostInfo: HostInfo, - isDeep = false + isNested = false ): Promise { // Windows の場合は, hostname が以下のループバックアドレスが割り当てられているか確認 const parse4windows = (): string | undefined => { @@ -72,7 +72,7 @@ async function getPidFromPort( portLog( hostInfo.port, "Hostname is loopback address; Getting process id from all loopback addresses...", - isDeep + isNested ); const pidArr: (number | undefined)[] = []; @@ -88,7 +88,7 @@ async function getPidFromPort( `| ${hostname}\t-> ${ pid == null ? "Assignable" : `pid=${pid} uses this port` }`, - isDeep + isNested ); pidArr.push(pid); @@ -99,7 +99,7 @@ async function getPidFromPort( } }; - portLog(hostInfo.port, "Getting process id...", isDeep); + portLog(hostInfo.port, "Getting process id...", isNested); const exec = isWindows ? { @@ -114,7 +114,7 @@ async function getPidFromPort( portLog( hostInfo.port, `Running command: "${exec.cmd} ${exec.args.join(" ")}"...`, - isDeep + isNested ); const stdout = execFileSync(exec.cmd, exec.args, { @@ -125,11 +125,15 @@ async function getPidFromPort( const pid = isWindows ? parse4windows() : stdout; if (pid == null || !pid.length) { - portLog(hostInfo.port, "Assignable; Nobody uses this port!", isDeep); + portLog(hostInfo.port, "Assignable; Nobody uses this port!", isNested); return undefined; } - portWarn(hostInfo.port, `Nonassignable; pid=${pid} uses this port!`, isDeep); + portWarn( + hostInfo.port, + `Nonassignable; pid=${pid} uses this port!`, + isNested + ); return Number(pid); } diff --git a/src/views/EditorHome.vue b/src/views/EditorHome.vue index 1774f4390d..3e6a83162e 100644 --- a/src/views/EditorHome.vue +++ b/src/views/EditorHome.vue @@ -638,12 +638,8 @@ watch( for (const engineId of store.state.engineIds) { const engineName = store.state.engineInfos[engineId].name; const altPort = newAltPortInfos[engineId]; - - console.log({ altPort }); - if (!altPort) return; - console.log("notices"); $q.notify({ message: `${altPort.from}番ポートが使用中であるため ${engineName} は、${altPort.to}番ポートで起動しました`, color: "toast", From d815c83452c5b65f71e9227b2a3f2476f11908ff Mon Sep 17 00:00:00 2001 From: wappon-28-dev Date: Fri, 19 May 2023 02:58:11 +0900 Subject: [PATCH 04/12] =?UTF-8?q?Fix:=20=E3=82=B3=E3=83=A1=E3=83=B3?= =?UTF-8?q?=E3=83=88=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/background/portManager.ts | 4 ++-- src/views/EditorHome.vue | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/background/portManager.ts b/src/background/portManager.ts index 254e11a74c..826166f067 100644 --- a/src/background/portManager.ts +++ b/src/background/portManager.ts @@ -23,7 +23,7 @@ function url2HostInfo(url: URL) { } /** - * "netstat -ano" の stdout から, 指定したポートを使用しているプロセスの process id を取得する. + * "netstat -ano" の stdout から, 指定したポートを使用しているプロセスの process id を取得します. * また, TCPの状態が TIME_WAIT のときはポートが割り当て可能だとみなします. * * ex) stdout: @@ -121,7 +121,7 @@ async function getPidFromPort( shell: true, }).toString(); - // Windows の場合は, lsof のように port と pid が 1to1 で取れないので, netstat の stdout からパース + // Windows の場合は, lsof のように port と pid が 1to1 で取れないので, netstat の stdout をパース const pid = isWindows ? parse4windows() : stdout; if (pid == null || !pid.length) { diff --git a/src/views/EditorHome.vue b/src/views/EditorHome.vue index 3e6a83162e..f4120b27ca 100644 --- a/src/views/EditorHome.vue +++ b/src/views/EditorHome.vue @@ -627,7 +627,7 @@ watch(allEngineState, (newEngineState) => { watch( () => store.state.altPortInfos, async (newAltPortInfos) => { - // この watch が, エンジンが起動した時 (=> 設定ファイルを読み込む前) に発火して + // この watch がエンジンが起動した時 (=> 設定ファイルを読み込む前) に発火して, // "今後この通知をしない" を無視するのを防ぐために, 初期化処理 (=> 設定ファイルが読み込まれる) まで待つ if (!isCompletedInitialStartup.value) return; From 7988e28a170e8ab3da4a8688d95fb4e8eee993e6 Mon Sep 17 00:00:00 2001 From: wappon-28-dev Date: Fri, 19 May 2023 16:08:58 +0900 Subject: [PATCH 05/12] =?UTF-8?q?Fix:=20eslint=E3=81=AEdisable=E3=81=AE?= =?UTF-8?q?=E8=A1=8C=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/background/portManager.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/background/portManager.ts b/src/background/portManager.ts index 826166f067..7cfab5b512 100644 --- a/src/background/portManager.ts +++ b/src/background/portManager.ts @@ -8,10 +8,8 @@ type HostInfo = { port: number; }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any const portLog = (port: number, message: string, isNested = false) => log.info(`${isNested ? "| " : ""}PORT ${port}: ${message}`); -// eslint-disable-next-line @typescript-eslint/no-explicit-any const portWarn = (port: number, message: string, isNested = false) => log.warn(`${isNested ? "| " : ""}PORT ${port}: ${message}`); From 1524d7f87a042af6c670e43a527953352a718c19 Mon Sep 17 00:00:00 2001 From: wappon-28-dev Date: Sat, 20 May 2023 22:04:17 +0900 Subject: [PATCH 06/12] =?UTF-8?q?Add:=20isVuexReady=20=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/engine.ts | 6 ++---- src/store/type.ts | 2 ++ src/store/ui.ts | 7 ++++++- src/views/EditorHome.vue | 20 +++++++++----------- tests/unit/store/Vuex.spec.ts | 1 + 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/store/engine.ts b/src/store/engine.ts index 53e3e7c2a6..b9b5bb7c7a 100644 --- a/src/store/engine.ts +++ b/src/store/engine.ts @@ -12,7 +12,7 @@ export const engineStoreState: EngineStoreState = { export const engineStore = createPartialStore({ GET_ENGINE_INFOS: { - async action({ state, commit, dispatch }) { + async action({ state, commit }) { const engineInfos = await window.electron.engineInfos(); // マルチエンジンオフモード時はengineIdsをデフォルトエンジンのIDだけにする。 @@ -29,9 +29,6 @@ export const engineStore = createPartialStore({ engineIds, engineInfos, }); - - // 代替ポート情報を取得 → トースト通知が発火する - dispatch("GET_ALT_PORT_INFOS"); }, }, @@ -232,6 +229,7 @@ export const engineStore = createPartialStore({ POST_ENGINE_START: { async action({ state, dispatch }, { engineIds }) { + await dispatch("GET_ALT_PORT_INFOS"); const result = await Promise.all( engineIds.map(async (engineId) => { if (state.engineStates[engineId] === "STARTING") { diff --git a/src/store/type.ts b/src/store/type.ts index 5acdcdbb61..5e594812a5 100644 --- a/src/store/type.ts +++ b/src/store/type.ts @@ -1134,6 +1134,7 @@ export type UiStoreState = { isPinned: boolean; isFullscreen: boolean; progress: number; + isVuexReady: boolean; }; export type UiStoreTypes = { @@ -1205,6 +1206,7 @@ export type UiStoreTypes = { }; ON_VUEX_READY: { + mutation: void; action(): void; }; diff --git a/src/store/ui.ts b/src/store/ui.ts index 38908d18b9..9ee1c03d07 100644 --- a/src/store/ui.ts +++ b/src/store/ui.ts @@ -52,6 +52,7 @@ export const uiStoreState: UiStoreState = { isPinned: false, isFullscreen: false, progress: -1, + isVuexReady: false, }; export const uiStore = createPartialStore({ @@ -191,8 +192,12 @@ export const uiStore = createPartialStore({ }, ON_VUEX_READY: { - action() { + mutation(state) { + state.isVuexReady = true; + }, + action({ commit }) { window.electron.vuexReady(); + commit("ON_VUEX_READY"); }, }, diff --git a/src/views/EditorHome.vue b/src/views/EditorHome.vue index f4120b27ca..402d22e0e7 100644 --- a/src/views/EditorHome.vue +++ b/src/views/EditorHome.vue @@ -577,9 +577,6 @@ onMounted(async () => { store.state.acceptTerms !== "Accepted"; isCompletedInitialStartup.value = true; - - // 代替ポート情報を取得 → トースト通知が発火する - await store.dispatch("GET_ALT_PORT_INFOS"); }); // エンジン待機 @@ -625,19 +622,20 @@ watch(allEngineState, (newEngineState) => { // 代替ポート情報の変更を監視 watch( - () => store.state.altPortInfos, - async (newAltPortInfos) => { - // この watch がエンジンが起動した時 (=> 設定ファイルを読み込む前) に発火して, - // "今後この通知をしない" を無視するのを防ぐために, 初期化処理 (=> 設定ファイルが読み込まれる) まで待つ - if (!isCompletedInitialStartup.value) return; + () => [store.state.altPortInfos, store.state.isVuexReady], + async () => { + const altPortInfos = store.state.altPortInfos; + const isVuexReady = store.state.isVuexReady; + const engineStartedOnAltPort = + store.state.confirmedTips.engineStartedOnAltPort; - // "今後この通知をしない" を考慮 - if (store.state.confirmedTips.engineStartedOnAltPort) return; + // この watch がエンジンが起動した時 (=> 設定ファイルを読み込む前) に発火して, "今後この通知をしない" を無視するのを防ぐ + if (!isVuexReady || engineStartedOnAltPort) return; // 代替ポートをトースト通知する for (const engineId of store.state.engineIds) { const engineName = store.state.engineInfos[engineId].name; - const altPort = newAltPortInfos[engineId]; + const altPort = altPortInfos[engineId]; if (!altPort) return; $q.notify({ diff --git a/tests/unit/store/Vuex.spec.ts b/tests/unit/store/Vuex.spec.ts index 4ab6aaeb03..3a72b900f8 100644 --- a/tests/unit/store/Vuex.spec.ts +++ b/tests/unit/store/Vuex.spec.ts @@ -139,6 +139,7 @@ describe("store/vuex.js test", () => { engineStartedOnAltPort: false, }, progress: -1, + isVuexReady: false, defaultPresetKeys: {}, }, getters: { From 5794248e75edc538b2c0dba99ff92f18df4d8944 Mon Sep 17 00:00:00 2001 From: wappon-28-dev Date: Sat, 20 May 2023 22:16:54 +0900 Subject: [PATCH 07/12] =?UTF-8?q?Fix:=20=E3=83=AC=E3=83=93=E3=83=A5?= =?UTF-8?q?=E3=83=BC=E5=8F=8D=E6=98=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/background/engineManager.ts | 2 +- src/background/portManager.ts | 27 +++++++++++++-------------- src/components/MenuBar.vue | 8 ++++++-- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/background/engineManager.ts b/src/background/engineManager.ts index 7679da4bdb..7a2ed9044b 100644 --- a/src/background/engineManager.ts +++ b/src/background/engineManager.ts @@ -253,7 +253,7 @@ export class EngineManager { const altPort = await findAltPort(engineHostInfo); // 代替ポートが見つからないとき - if (altPort == null) { + if (altPort == undefined) { log.error(`ENGINE ${engineId}: No Alternative Port Found`); dialog.showErrorBox( `${engineInfo.name} の起動に失敗しました`, diff --git a/src/background/portManager.ts b/src/background/portManager.ts index 7cfab5b512..e9b899341b 100644 --- a/src/background/portManager.ts +++ b/src/background/portManager.ts @@ -3,7 +3,7 @@ import log from "electron-log"; const isWindows = process.platform === "win32"; -type HostInfo = { +export type HostInfo = { hostname: string; port: number; }; @@ -13,7 +13,7 @@ const portLog = (port: number, message: string, isNested = false) => const portWarn = (port: number, message: string, isNested = false) => log.warn(`${isNested ? "| " : ""}PORT ${port}: ${message}`); -function url2HostInfo(url: URL) { +export function url2HostInfo(url: URL) { return { hostname: url.hostname, port: Number(url.port), @@ -58,12 +58,12 @@ function netstatStdout2pid( return undefined; } -async function getPidFromPort( +export async function getPidFromPort( hostInfo: HostInfo, - isNested = false + isNested = false // ログ整形用の引数 ): Promise { // Windows の場合は, hostname が以下のループバックアドレスが割り当てられているか確認 - const parse4windows = (): string | undefined => { + const parse4windows = (stdout: string): string | undefined => { // それぞれのループバックアドレスに対して pid を取得 const loopbackAddr = ["localhost", "127.0.0.1", "0.0.0.0", "[::1]"]; if (loopbackAddr.includes(hostInfo.hostname)) { @@ -84,7 +84,7 @@ async function getPidFromPort( portLog( hostInfo.port, `| ${hostname}\t-> ${ - pid == null ? "Assignable" : `pid=${pid} uses this port` + pid == undefined ? "Assignable" : `pid=${pid} uses this port` }`, isNested ); @@ -120,9 +120,9 @@ async function getPidFromPort( }).toString(); // Windows の場合は, lsof のように port と pid が 1to1 で取れないので, netstat の stdout をパース - const pid = isWindows ? parse4windows() : stdout; + const pid = isWindows ? parse4windows(stdout) : stdout; - if (pid == null || !pid.length) { + if (pid == undefined || !pid.length) { portLog(hostInfo.port, "Assignable; Nobody uses this port!", isNested); return undefined; } @@ -135,7 +135,7 @@ async function getPidFromPort( return Number(pid); } -async function getProcessNameFromPid( +export async function getProcessNameFromPid( hostInfo: HostInfo, pid: number ): Promise { @@ -172,7 +172,9 @@ async function getProcessNameFromPid( * @param hostInfo ホスト情報 * @returns 割り当て可能なポート番号 or `undefined` (割り当て可能なポートが見つからなかったとき) */ -async function findAltPort(hostInfo: HostInfo): Promise { +export async function findAltPort( + hostInfo: HostInfo +): Promise { const basePort = hostInfo.port; portLog(hostInfo.port, `Find another assignable port from ${basePort}...`); @@ -190,7 +192,7 @@ async function findAltPort(hostInfo: HostInfo): Promise { ); // ポートを既に割り当てられているプロセスidの取得: undefined → ポートが空いている - if (altPid == null) return altPort; + if (altPid == undefined) return altPort; } portWarn( @@ -199,6 +201,3 @@ async function findAltPort(hostInfo: HostInfo): Promise { ); return undefined; } - -export type { HostInfo }; -export { url2HostInfo, getPidFromPort, getProcessNameFromPid, findAltPort }; diff --git a/src/components/MenuBar.vue b/src/components/MenuBar.vue index ed4acf4362..1b4dff7250 100644 --- a/src/components/MenuBar.vue +++ b/src/components/MenuBar.vue @@ -79,10 +79,14 @@ const defaultEngineAltPortTo = computed(() => { const defaultEngineInfo = Object.values(store.state.engineInfos).find( (engine) => engine.type === "default" ); - if (defaultEngineInfo == null) return undefined; + if (defaultEngineInfo == undefined) return undefined; // : { from: number, to: number } -> to (代替先ポート) - return altPortInfos[defaultEngineInfo.uuid]?.to; + if (defaultEngineInfo.uuid in altPortInfos) { + return altPortInfos[defaultEngineInfo.uuid].to; + } else { + return undefined; + } }); window.electron.getAppInfos().then((obj) => { From 61914ed3c6e488084f30fa62cce9fafa3a4275a7 Mon Sep 17 00:00:00 2001 From: wappon-28-dev Date: Mon, 22 May 2023 00:35:08 +0900 Subject: [PATCH 08/12] =?UTF-8?q?fix:=20=E3=83=AC=E3=83=93=E3=83=A5?= =?UTF-8?q?=E3=83=BC=E3=82=92=E5=8F=8D=E6=98=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - !isVuexReady を上に - 2行のとこ反転 --- src/background.ts | 2 +- src/views/EditorHome.vue | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/background.ts b/src/background.ts index 22991970c0..0b6b78a700 100644 --- a/src/background.ts +++ b/src/background.ts @@ -524,8 +524,8 @@ async function start() { } store.set("engineSettings", engineSettings); - await createWindow(); await engineManager.runEngineAll(win); + await createWindow(); } const menuTemplateForMac: Electron.MenuItemConstructorOptions[] = [ diff --git a/src/views/EditorHome.vue b/src/views/EditorHome.vue index 402d22e0e7..f0619ef524 100644 --- a/src/views/EditorHome.vue +++ b/src/views/EditorHome.vue @@ -624,18 +624,16 @@ watch(allEngineState, (newEngineState) => { watch( () => [store.state.altPortInfos, store.state.isVuexReady], async () => { - const altPortInfos = store.state.altPortInfos; - const isVuexReady = store.state.isVuexReady; - const engineStartedOnAltPort = - store.state.confirmedTips.engineStartedOnAltPort; - // この watch がエンジンが起動した時 (=> 設定ファイルを読み込む前) に発火して, "今後この通知をしない" を無視するのを防ぐ - if (!isVuexReady || engineStartedOnAltPort) return; + if (!store.state.isVuexReady) return; + + // "今後この通知をしない" を考慮 + if (store.state.confirmedTips.engineStartedOnAltPort) return; // 代替ポートをトースト通知する for (const engineId of store.state.engineIds) { const engineName = store.state.engineInfos[engineId].name; - const altPort = altPortInfos[engineId]; + const altPort = store.state.altPortInfos[engineId]; if (!altPort) return; $q.notify({ From 10b0917b81741085b10afc699d5085bbb012f6dd Mon Sep 17 00:00:00 2001 From: wappon-28-dev Date: Sun, 28 May 2023 13:10:03 +0900 Subject: [PATCH 09/12] =?UTF-8?q?Fix:=20=E3=83=AC=E3=83=93=E3=83=A5?= =?UTF-8?q?=E3=83=BC=E5=8F=8D=E6=98=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - basePortを定義したのに全然使われてなかったので使った --- src/background/portManager.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/background/portManager.ts b/src/background/portManager.ts index e9b899341b..7a7434a2df 100644 --- a/src/background/portManager.ts +++ b/src/background/portManager.ts @@ -66,7 +66,14 @@ export async function getPidFromPort( const parse4windows = (stdout: string): string | undefined => { // それぞれのループバックアドレスに対して pid を取得 const loopbackAddr = ["localhost", "127.0.0.1", "0.0.0.0", "[::1]"]; - if (loopbackAddr.includes(hostInfo.hostname)) { + if (!loopbackAddr.includes(hostInfo.hostname)) { + portLog( + hostInfo.port, + `Hostname is not loopback address; Getting process id from ${hostInfo.hostname}...`, + isNested + ); + return netstatStdout2pid(stdout, hostInfo)?.toString(); + } else { portLog( hostInfo.port, "Hostname is loopback address; Getting process id from all loopback addresses...", @@ -176,13 +183,13 @@ export async function findAltPort( hostInfo: HostInfo ): Promise { const basePort = hostInfo.port; - portLog(hostInfo.port, `Find another assignable port from ${basePort}...`); + portLog(basePort, `Find another assignable port from ${basePort}...`); // エンジン指定のポート + 100番までを探索 エフェメラルポートの範囲の最大は超えないようにする const altPortMax = Math.min(basePort + 100, 65535); for (let altPort = basePort + 1; altPort <= altPortMax; altPort++) { - portLog(hostInfo.port, `Trying whether port ${altPort} is assignable...`); + portLog(basePort, `Trying whether port ${altPort} is assignable...`); const altPid = await getPidFromPort( { hostname: hostInfo.hostname, @@ -195,9 +202,6 @@ export async function findAltPort( if (altPid == undefined) return altPort; } - portWarn( - hostInfo.port, - `No alternative port found! ${basePort}...${altPortMax}` - ); + portWarn(basePort, `No alternative port found! ${basePort}...${altPortMax}`); return undefined; } From f41106abc2b82a06cd7deb1866252f3794affc01 Mon Sep 17 00:00:00 2001 From: wappon-28-dev Date: Tue, 30 May 2023 23:37:52 +0900 Subject: [PATCH 10/12] =?UTF-8?q?Fix:=20=E3=83=97=E3=83=AD=E3=83=88?= =?UTF-8?q?=E3=82=B3=E3=83=AB=E3=81=AE=E3=83=9B=E3=83=AB=E3=83=80=E3=83=BC?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ここまで来たらURLを引数に渡しても良いかもと思った --- src/background/engineManager.ts | 4 ++-- src/background/portManager.ts | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/background/engineManager.ts b/src/background/engineManager.ts index 7a2ed9044b..3617b53188 100644 --- a/src/background/engineManager.ts +++ b/src/background/engineManager.ts @@ -243,7 +243,7 @@ export class EngineManager { // ポートを既に割り当てているプロセスidの取得: undefined → ポートが空いている const pid = await getPidFromPort(engineHostInfo); - if (pid != null) { + if (pid != undefined) { const processName = await getProcessNameFromPid(engineHostInfo, pid); log.warn( `ENGINE ${engineId}: Port ${engineHostInfo.port} has already been assigned by ${processName} (pid=${pid})` @@ -270,7 +270,7 @@ export class EngineManager { }; // 代替ポートを設定 - engineInfo.host = `http://${engineHostInfo.hostname}:${altPort}`; + engineInfo.host = `${engineHostInfo}://${engineHostInfo.hostname}:${altPort}`; log.warn( `ENGINE ${engineId}: Applied Alternative Port: ${engineHostInfo.port} -> ${altPort}` ); diff --git a/src/background/portManager.ts b/src/background/portManager.ts index 7a7434a2df..6abe124da8 100644 --- a/src/background/portManager.ts +++ b/src/background/portManager.ts @@ -4,6 +4,7 @@ import log from "electron-log"; const isWindows = process.platform === "win32"; export type HostInfo = { + protocol: string; hostname: string; port: number; }; @@ -13,8 +14,9 @@ const portLog = (port: number, message: string, isNested = false) => const portWarn = (port: number, message: string, isNested = false) => log.warn(`${isNested ? "| " : ""}PORT ${port}: ${message}`); -export function url2HostInfo(url: URL) { +export function url2HostInfo(url: URL): HostInfo { return { + protocol: url.protocol, hostname: url.hostname, port: Number(url.port), }; @@ -84,6 +86,7 @@ export async function getPidFromPort( loopbackAddr.forEach((hostname) => { // netstat の stdout から pid を取得 const pid = netstatStdout2pid(stdout, { + protocol: hostInfo.protocol, hostname, port: hostInfo.port, }); @@ -192,6 +195,7 @@ export async function findAltPort( portLog(basePort, `Trying whether port ${altPort} is assignable...`); const altPid = await getPidFromPort( { + protocol: hostInfo.protocol, hostname: hostInfo.hostname, port: altPort, }, From ee9c644b31ae2508b8ca49497fcc415dae390d0a Mon Sep 17 00:00:00 2001 From: wappon_28_dev Date: Fri, 2 Jun 2023 00:41:36 +0900 Subject: [PATCH 11/12] =?UTF-8?q?=E3=83=97=E3=83=AD=E3=83=88=E3=82=B3?= =?UTF-8?q?=E3=83=AB=E3=81=AE=E9=83=A8=E5=88=86=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: sabonerune <102559104+sabonerune@users.noreply.github.com> --- src/background/engineManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/background/engineManager.ts b/src/background/engineManager.ts index 3617b53188..cb0263fb2f 100644 --- a/src/background/engineManager.ts +++ b/src/background/engineManager.ts @@ -270,7 +270,7 @@ export class EngineManager { }; // 代替ポートを設定 - engineInfo.host = `${engineHostInfo}://${engineHostInfo.hostname}:${altPort}`; + engineInfo.host = `${engineHostInfo.protocol}//${engineHostInfo.hostname}:${altPort}`; log.warn( `ENGINE ${engineId}: Applied Alternative Port: ${engineHostInfo.port} -> ${altPort}` ); From 93bf24d2afdab0949dce8e49dbd16ebbc2c15c60 Mon Sep 17 00:00:00 2001 From: wappon-28-dev Date: Fri, 2 Jun 2023 23:42:31 +0900 Subject: [PATCH 12/12] =?UTF-8?q?Fix:=20=E5=89=B2=E3=82=8A=E5=BD=93?= =?UTF-8?q?=E3=81=A6=E5=8F=AF=E8=83=BD=E3=81=AA=E5=88=A4=E5=AE=9A=E3=82=92?= =?UTF-8?q?=20LISTENING=20=E4=BB=A5=E5=A4=96=E3=81=AE=E3=81=BF=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit resolve: #1326 --- src/background/portManager.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/background/portManager.ts b/src/background/portManager.ts index 6abe124da8..fd579a307b 100644 --- a/src/background/portManager.ts +++ b/src/background/portManager.ts @@ -23,8 +23,7 @@ export function url2HostInfo(url: URL): HostInfo { } /** - * "netstat -ano" の stdout から, 指定したポートを使用しているプロセスの process id を取得します. - * また, TCPの状態が TIME_WAIT のときはポートが割り当て可能だとみなします. + * "netstat -ano" の stdout から, 指定したポートを LISTENING しているプロセスの id を取得します. * * ex) stdout: * ``` cmd @@ -50,10 +49,7 @@ function netstatStdout2pid( const pid = parts[parts.length - 1]; const tcpState = parts[parts.length - 2]; - // 他のプロセスが割り当てをしているとみなすTCPの状態 - if (["LISTENING", "ESTABLISHED", "CLOSE_WAIT"].includes(tcpState)) { - return Number(pid); - } + if (tcpState === "LISTENING") return Number(pid); } }