fix(cli-run): attach to default server when auto port range exhausted
This commit is contained in:
@@ -177,6 +177,28 @@ describe("createServerConnection", () => {
|
||||
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 () => {
|
||||
// given
|
||||
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}`)
|
||||
}
|
||||
|
||||
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> {
|
||||
const { signal, port } = options
|
||||
const { client, server } = await withWorkingOpencodePath(() =>
|
||||
@@ -67,7 +75,27 @@ export async function createServerConnection(options: {
|
||||
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) {
|
||||
console.log(pc.dim("Auto-selected port"), pc.cyan(selectedPort.toString()))
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user