fix(cli-run): attach to default server when auto port range exhausted
This commit is contained in:
parent
ada8c127aa
commit
dacada152a
@ -177,6 +177,28 @@ describe("createServerConnection", () => {
|
|||||||
expect(mockServerClose).toHaveBeenCalledTimes(1)
|
expect(mockServerClose).toHaveBeenCalledTimes(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("auto mode attaches to default server when port range is exhausted", async () => {
|
||||||
|
// given
|
||||||
|
const signal = new AbortController().signal
|
||||||
|
mockGetAvailableServerPort.mockRejectedValueOnce(
|
||||||
|
new Error("No available port found in range 4097-4116"),
|
||||||
|
)
|
||||||
|
mockIsPortAvailable.mockResolvedValueOnce(false)
|
||||||
|
|
||||||
|
// when
|
||||||
|
const result = await createServerConnection({ signal })
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(mockGetAvailableServerPort).toHaveBeenCalledWith(4096, "127.0.0.1")
|
||||||
|
expect(mockIsPortAvailable).toHaveBeenCalledWith(4096, "127.0.0.1")
|
||||||
|
expect(mockCreateOpencodeClient).toHaveBeenCalledWith({
|
||||||
|
baseUrl: "http://127.0.0.1:4096",
|
||||||
|
})
|
||||||
|
expect(mockCreateOpencode).not.toHaveBeenCalled()
|
||||||
|
result.cleanup()
|
||||||
|
expect(mockServerClose).not.toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
it("invalid port throws error", async () => {
|
it("invalid port throws error", async () => {
|
||||||
// given
|
// given
|
||||||
const signal = new AbortController().signal
|
const signal = new AbortController().signal
|
||||||
|
|||||||
@ -12,6 +12,14 @@ function isPortStartFailure(error: unknown, port: number): boolean {
|
|||||||
return error.message.includes(`Failed to start server on port ${port}`)
|
return error.message.includes(`Failed to start server on port ${port}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isPortRangeExhausted(error: unknown): boolean {
|
||||||
|
if (!(error instanceof Error)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return error.message.includes("No available port found in range")
|
||||||
|
}
|
||||||
|
|
||||||
async function startServer(options: { signal: AbortSignal, port: number }): Promise<ServerConnection> {
|
async function startServer(options: { signal: AbortSignal, port: number }): Promise<ServerConnection> {
|
||||||
const { signal, port } = options
|
const { signal, port } = options
|
||||||
const { client, server } = await withWorkingOpencodePath(() =>
|
const { client, server } = await withWorkingOpencodePath(() =>
|
||||||
@ -67,7 +75,27 @@ export async function createServerConnection(options: {
|
|||||||
return { client, cleanup: () => {} }
|
return { client, cleanup: () => {} }
|
||||||
}
|
}
|
||||||
|
|
||||||
const { port: selectedPort, wasAutoSelected } = await getAvailableServerPort(DEFAULT_SERVER_PORT, "127.0.0.1")
|
let selectedPort: number
|
||||||
|
let wasAutoSelected: boolean
|
||||||
|
try {
|
||||||
|
const selected = await getAvailableServerPort(DEFAULT_SERVER_PORT, "127.0.0.1")
|
||||||
|
selectedPort = selected.port
|
||||||
|
wasAutoSelected = selected.wasAutoSelected
|
||||||
|
} catch (error) {
|
||||||
|
if (!isPortRangeExhausted(error)) {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultPortIsAvailable = await isPortAvailable(DEFAULT_SERVER_PORT, "127.0.0.1")
|
||||||
|
if (defaultPortIsAvailable) {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(pc.dim("Port range exhausted, attaching to existing server on"), pc.cyan(DEFAULT_SERVER_PORT.toString()))
|
||||||
|
const client = createOpencodeClient({ baseUrl: `http://127.0.0.1:${DEFAULT_SERVER_PORT}` })
|
||||||
|
return { client, cleanup: () => {} }
|
||||||
|
}
|
||||||
|
|
||||||
if (wasAutoSelected) {
|
if (wasAutoSelected) {
|
||||||
console.log(pc.dim("Auto-selected port"), pc.cyan(selectedPort.toString()))
|
console.log(pc.dim("Auto-selected port"), pc.cyan(selectedPort.toString()))
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user