fix: check if port is occupied before start local server (#2098)

Signed-off-by: James <james@jan.ai>
Co-authored-by: James <james@jan.ai>
This commit is contained in:
NamH 2024-02-19 22:39:14 +07:00 committed by GitHub
parent 53006dd26e
commit 5c7b791c26
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 52 additions and 21 deletions

View File

@ -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'

View File

@ -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<boolean> => {
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

View File

@ -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 (
<div className="flex h-full w-full" data-testid="local-server-testid">
{/* 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
</Button>