port occupied detection
This commit is contained in:
parent
fed1594ddc
commit
0d99e5549e
@ -5,12 +5,15 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"embed"
|
"embed"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -205,3 +208,12 @@ func Unzip(source, destination string) error {
|
|||||||
}
|
}
|
||||||
return nil
|
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
|
||||||
|
}
|
||||||
|
@ -261,5 +261,6 @@
|
|||||||
"The content of file": "ファイル",
|
"The content of file": "ファイル",
|
||||||
"is as follows. When replying to me, consider the file content and respond accordingly:": "の内容は以下の通りです。私に返信する際は、ファイルの内容を考慮して適切に返信してください:",
|
"is as follows. When replying to me, consider the file content and respond accordingly:": "の内容は以下の通りです。私に返信する際は、ファイルの内容を考慮して適切に返信してください:",
|
||||||
"What's the file name": "ファイル名は何ですか",
|
"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.": "ポートが占有されています。設定ページで変更するか、ポートを占有しているプログラムを終了してください。"
|
||||||
}
|
}
|
@ -261,5 +261,6 @@
|
|||||||
"The content of file": "文件",
|
"The content of file": "文件",
|
||||||
"is as follows. When replying to me, consider the file content and respond accordingly:": "内容如下。回复时考虑文件内容并做出相应回复:",
|
"is as follows. When replying to me, consider the file content and respond accordingly:": "内容如下。回复时考虑文件内容并做出相应回复:",
|
||||||
"What's the file name": "文件名是什么",
|
"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.": "端口被占用。请在配置页面更改端口,或关闭占用端口的程序"
|
||||||
}
|
}
|
@ -1,6 +1,12 @@
|
|||||||
import React, { FC, MouseEventHandler, ReactElement } from 'react';
|
import React, { FC, MouseEventHandler, ReactElement } from 'react';
|
||||||
import commonStore, { ModelStatus } from '../stores/commonStore';
|
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 { Button } from '@fluentui/react-components';
|
||||||
import { observer } from 'mobx-react-lite';
|
import { observer } from 'mobx-react-lite';
|
||||||
import { exit, getStatus, readRoot, switchModel, updateConfig } from '../apis';
|
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;
|
const port = modelConfig.apiParameters.apiPort;
|
||||||
|
|
||||||
|
if (!await IsPortAvailable(port)) {
|
||||||
await exit(1000).catch(() => {
|
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 ?
|
const startServer = webgpu ?
|
||||||
(_: string, port: number, host: string) => StartWebGPUServer(port, host)
|
(_: 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.',
|
'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.',
|
'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.',
|
'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 matchedError = Object.entries(errorsMap).find(([key, _]) => error.includes(key));
|
||||||
const message = matchedError ? t(matchedError[1]) : error;
|
const message = matchedError ? t(matchedError[1]) : error;
|
||||||
|
2
frontend/wailsjs/go/backend_golang/App.d.ts
generated
vendored
2
frontend/wailsjs/go/backend_golang/App.d.ts
generated
vendored
@ -28,6 +28,8 @@ export function GetPyError():Promise<string>;
|
|||||||
|
|
||||||
export function InstallPyDep(arg1:string,arg2:boolean):Promise<string>;
|
export function InstallPyDep(arg1:string,arg2:boolean):Promise<string>;
|
||||||
|
|
||||||
|
export function IsPortAvailable(arg1:number):Promise<boolean>;
|
||||||
|
|
||||||
export function ListDirFiles(arg1:string):Promise<Array<backend_golang.FileInfo>>;
|
export function ListDirFiles(arg1:string):Promise<Array<backend_golang.FileInfo>>;
|
||||||
|
|
||||||
export function MergeLora(arg1:string,arg2:boolean,arg3:number,arg4:string,arg5:string,arg6:string):Promise<string>;
|
export function MergeLora(arg1:string,arg2:boolean,arg3:number,arg4:string,arg5:string,arg6:string):Promise<string>;
|
||||||
|
4
frontend/wailsjs/go/backend_golang/App.js
generated
4
frontend/wailsjs/go/backend_golang/App.js
generated
@ -54,6 +54,10 @@ export function InstallPyDep(arg1, arg2) {
|
|||||||
return window['go']['backend_golang']['App']['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) {
|
export function ListDirFiles(arg1) {
|
||||||
return window['go']['backend_golang']['App']['ListDirFiles'](arg1);
|
return window['go']['backend_golang']['App']['ListDirFiles'](arg1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user