From 5c7b791c26d791286c6c464e6c45a68f37f62d45 Mon Sep 17 00:00:00 2001 From: NamH Date: Mon, 19 Feb 2024 22:39:14 +0700 Subject: [PATCH] fix: check if port is occupied before start local server (#2098) Signed-off-by: James Co-authored-by: James --- core/src/node/api/processors/app.ts | 1 - server/index.ts | 10 +++++ web/screens/LocalServer/index.tsx | 62 +++++++++++++++++++---------- 3 files changed, 52 insertions(+), 21 deletions(-) diff --git a/core/src/node/api/processors/app.ts b/core/src/node/api/processors/app.ts index a4b1a5a066..c62b5011d8 100644 --- a/core/src/node/api/processors/app.ts +++ b/core/src/node/api/processors/app.ts @@ -1,6 +1,5 @@ import { basename, isAbsolute, join, relative } from 'path' -import { AppRoute } from '../../../api' import { Processor } from './Processor' import { getAppConfigurations as appConfiguration, updateAppConfiguration } from '../../helper' import { log as writeLog, logServer as writeServerLog } from '../../helper/log' diff --git a/server/index.ts b/server/index.ts index 8e63eb46ad..98cc8385d1 100644 --- a/server/index.ts +++ b/server/index.ts @@ -7,6 +7,7 @@ import { getJanExtensionsPath, } from '@janhq/core/node' import { join } from 'path' +import tcpPortUsed from 'tcp-port-used' // Load environment variables dotenv.config() @@ -46,6 +47,15 @@ export interface ServerConfig { * @param configs - Server configurations */ export const startServer = async (configs?: ServerConfig): Promise => { + if (configs?.port && configs?.host) { + const inUse = await tcpPortUsed.check(Number(configs.port), configs.host) + if (inUse) { + const errorMessage = `Port ${configs.port} is already in use.` + logServer(errorMessage) + throw new Error(errorMessage) + } + } + // Update server settings isVerbose = configs?.isVerboseEnabled ?? true hostSetting = configs?.host ?? JAN_API_HOST diff --git a/web/screens/LocalServer/index.tsx b/web/screens/LocalServer/index.tsx index 69c9260215..f9c2cf7194 100644 --- a/web/screens/LocalServer/index.tsx +++ b/web/screens/LocalServer/index.tsx @@ -39,6 +39,8 @@ import ModalTroubleShooting, { } from '@/containers/ModalTroubleShoot' import ServerLogs from '@/containers/ServerLogs' +import { toaster } from '@/containers/Toast' + import { loadModelErrorAtom, useActiveModel } from '@/hooks/useActiveModel' import { useLogs } from '@/hooks/useLogs' @@ -106,6 +108,45 @@ const LocalServerScreen = () => { handleChangePort(port) }, [handleChangePort, port]) + const onStartServerClick = async () => { + if (selectedModel == null) return + try { + const isStarted = await window.core?.api?.startServer({ + host, + port, + isCorsEnabled, + isVerboseEnabled, + }) + await startModel(selectedModel.id) + if (isStarted) setServerEnabled(true) + if (firstTimeVisitAPIServer) { + localStorage.setItem(FIRST_TIME_VISIT_API_SERVER, 'false') + setFirstTimeVisitAPIServer(false) + } + } catch (e) { + console.error(e) + toaster({ + title: `Failed to start server!`, + description: 'Please check Server Logs for more details.', + type: 'error', + }) + } + } + + const onStopServerClick = async () => { + window.core?.api?.stopServer() + setServerEnabled(false) + setLoadModelError(undefined) + } + + const onToggleServer = async () => { + if (serverEnabled) { + await onStopServerClick() + } else { + await onStartServerClick() + } + } + return (
{/* Left SideBar */} @@ -122,26 +163,7 @@ const LocalServerScreen = () => { block themes={serverEnabled ? 'danger' : 'primary'} disabled={stateModel.loading || errorRangePort || !selectedModel} - onClick={async () => { - if (serverEnabled) { - window.core?.api?.stopServer() - setServerEnabled(false) - setLoadModelError(undefined) - } else { - startModel(String(selectedModel?.id)) - const isStarted = await window.core?.api?.startServer({ - host, - port, - isCorsEnabled, - isVerboseEnabled, - }) - if (isStarted) setServerEnabled(true) - if (firstTimeVisitAPIServer) { - localStorage.setItem(FIRST_TIME_VISIT_API_SERVER, 'false') - setFirstTimeVisitAPIServer(false) - } - } - }} + onClick={onToggleServer} > {serverEnabled ? 'Stop' : 'Start'} Server