From 0d99e5549e1625d4cdc9ff8e11167f44c896e754 Mon Sep 17 00:00:00 2001 From: josc146 Date: Fri, 3 Nov 2023 21:18:42 +0800 Subject: [PATCH] port occupied detection --- backend-golang/utils.go | 12 ++++++++++++ frontend/src/_locales/ja/main.json | 3 ++- frontend/src/_locales/zh-hans/main.json | 3 ++- frontend/src/components/RunButton.tsx | 21 +++++++++++++++++---- frontend/wailsjs/go/backend_golang/App.d.ts | 2 ++ frontend/wailsjs/go/backend_golang/App.js | 4 ++++ 6 files changed, 39 insertions(+), 6 deletions(-) diff --git a/backend-golang/utils.go b/backend-golang/utils.go index 455c458..64594fe 100644 --- a/backend-golang/utils.go +++ b/backend-golang/utils.go @@ -5,12 +5,15 @@ import ( "bufio" "embed" "errors" + "fmt" "io" "io/fs" + "net" "os" "os/exec" "path/filepath" "runtime" + "strconv" "strings" ) @@ -205,3 +208,12 @@ func Unzip(source, destination string) error { } return nil } + +func (a *App) IsPortAvailable(port int) bool { + l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%s", strconv.Itoa(port))) + if err != nil { + return false + } + defer l.Close() + return true +} diff --git a/frontend/src/_locales/ja/main.json b/frontend/src/_locales/ja/main.json index 3fcd2b1..66e1baf 100644 --- a/frontend/src/_locales/ja/main.json +++ b/frontend/src/_locales/ja/main.json @@ -261,5 +261,6 @@ "The content of file": "ファイル", "is as follows. When replying to me, consider the file content and respond accordingly:": "の内容は以下の通りです。私に返信する際は、ファイルの内容を考慮して適切に返信してください:", "What's the file name": "ファイル名は何ですか", - "The file name is: ": "ファイル名は次のとおりです: " + "The file name is: ": "ファイル名は次のとおりです: ", + "Port is occupied. Change it in Configs page or close the program that occupies the port.": "ポートが占有されています。設定ページで変更するか、ポートを占有しているプログラムを終了してください。" } \ No newline at end of file diff --git a/frontend/src/_locales/zh-hans/main.json b/frontend/src/_locales/zh-hans/main.json index 4cac8a9..f3eceb1 100644 --- a/frontend/src/_locales/zh-hans/main.json +++ b/frontend/src/_locales/zh-hans/main.json @@ -261,5 +261,6 @@ "The content of file": "文件", "is as follows. When replying to me, consider the file content and respond accordingly:": "内容如下。回复时考虑文件内容并做出相应回复:", "What's the file name": "文件名是什么", - "The file name is: ": "文件名是:" + "The file name is: ": "文件名是:", + "Port is occupied. Change it in Configs page or close the program that occupies the port.": "端口被占用。请在配置页面更改端口,或关闭占用端口的程序" } \ No newline at end of file diff --git a/frontend/src/components/RunButton.tsx b/frontend/src/components/RunButton.tsx index 4ade47f..5b5e7fe 100644 --- a/frontend/src/components/RunButton.tsx +++ b/frontend/src/components/RunButton.tsx @@ -1,6 +1,12 @@ import React, { FC, MouseEventHandler, ReactElement } from 'react'; import commonStore, { ModelStatus } from '../stores/commonStore'; -import { AddToDownloadList, FileExists, StartServer, StartWebGPUServer } from '../../wailsjs/go/backend_golang/App'; +import { + AddToDownloadList, + FileExists, + IsPortAvailable, + StartServer, + StartWebGPUServer +} from '../../wailsjs/go/backend_golang/App'; import { Button } from '@fluentui/react-components'; import { observer } from 'mobx-react-lite'; import { exit, getStatus, readRoot, switchModel, updateConfig } from '../apis'; @@ -107,8 +113,15 @@ export const RunButton: FC<{ onClickRun?: MouseEventHandler, iconMode?: boolean const port = modelConfig.apiParameters.apiPort; - await exit(1000).catch(() => { - }); + if (!await IsPortAvailable(port)) { + await exit(1000).catch(() => { + }); + if (!await IsPortAvailable(port)) { + toast(t('Port is occupied. Change it in Configs page or close the program that occupies the port.'), { type: 'error' }); + commonStore.setStatus({ status: ModelStatus.Offline }); + return; + } + } const startServer = webgpu ? (_: string, port: number, host: string) => StartWebGPUServer(port, host) @@ -211,7 +224,7 @@ export const RunButton: FC<{ onClickRun?: MouseEventHandler, iconMode?: boolean 'invalid header or archive is corrupted': 'The model file is corrupted, please download again.', 'no NVIDIA driver': 'Found no NVIDIA driver, please install the latest driver.', 'CUDA out of memory': 'VRAM is not enough, please reduce stored layers or use a lower precision in Configs page.', - 'Ninja is required to load C++ extensions': 'Failed to enable custom CUDA kernel, ninja is required to load C++ extensions. You may be using the CPU version of PyTorch, please reinstall PyTorch with CUDA. Or if you are using a custom Python interpreter, you must compile the CUDA kernel by yourself or disable Custom CUDA kernel acceleration.', + 'Ninja is required to load C++ extensions': 'Failed to enable custom CUDA kernel, ninja is required to load C++ extensions. You may be using the CPU version of PyTorch, please reinstall PyTorch with CUDA. Or if you are using a custom Python interpreter, you must compile the CUDA kernel by yourself or disable Custom CUDA kernel acceleration.' }; const matchedError = Object.entries(errorsMap).find(([key, _]) => error.includes(key)); const message = matchedError ? t(matchedError[1]) : error; diff --git a/frontend/wailsjs/go/backend_golang/App.d.ts b/frontend/wailsjs/go/backend_golang/App.d.ts index 1cd7217..ec1cdbb 100755 --- a/frontend/wailsjs/go/backend_golang/App.d.ts +++ b/frontend/wailsjs/go/backend_golang/App.d.ts @@ -28,6 +28,8 @@ export function GetPyError():Promise; export function InstallPyDep(arg1:string,arg2:boolean):Promise; +export function IsPortAvailable(arg1:number):Promise; + export function ListDirFiles(arg1:string):Promise>; export function MergeLora(arg1:string,arg2:boolean,arg3:number,arg4:string,arg5:string,arg6:string):Promise; diff --git a/frontend/wailsjs/go/backend_golang/App.js b/frontend/wailsjs/go/backend_golang/App.js index fcddc93..d63c473 100755 --- a/frontend/wailsjs/go/backend_golang/App.js +++ b/frontend/wailsjs/go/backend_golang/App.js @@ -54,6 +54,10 @@ export function InstallPyDep(arg1, arg2) { return window['go']['backend_golang']['App']['InstallPyDep'](arg1, arg2); } +export function IsPortAvailable(arg1) { + return window['go']['backend_golang']['App']['IsPortAvailable'](arg1); +} + export function ListDirFiles(arg1) { return window['go']['backend_golang']['App']['ListDirFiles'](arg1); }