Skip to content

Commit

Permalink
fix: check if port is occupied before start local server (janhq#2098)
Browse files Browse the repository at this point in the history
Signed-off-by: James <[email protected]>
Co-authored-by: James <[email protected]>
  • Loading branch information
namchuai and James authored Feb 19, 2024
1 parent 53006dd commit 5c7b791
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 21 deletions.
1 change: 0 additions & 1 deletion core/src/node/api/processors/app.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand Down
10 changes: 10 additions & 0 deletions server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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
Expand Down
62 changes: 42 additions & 20 deletions web/screens/LocalServer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down Expand Up @@ -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 */}
Expand All @@ -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>
Expand Down

0 comments on commit 5c7b791

Please sign in to comment.