app: refactor server management backend (#13813)
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import type { ServerConnection } from "@/context/server"
|
||||
import { checkServerHealth } from "./server-health"
|
||||
|
||||
const server: ServerConnection.HttpBase = {
|
||||
url: "http://localhost:4096",
|
||||
}
|
||||
|
||||
function abortFromInput(input: RequestInfo | URL, init?: RequestInit) {
|
||||
if (init?.signal) return init.signal
|
||||
if (input instanceof Request) return input.signal
|
||||
@@ -15,7 +20,7 @@ describe("checkServerHealth", () => {
|
||||
headers: { "content-type": "application/json" },
|
||||
})) as unknown as typeof globalThis.fetch
|
||||
|
||||
const result = await checkServerHealth("http://localhost:4096", fetch)
|
||||
const result = await checkServerHealth(server, fetch)
|
||||
|
||||
expect(result).toEqual({ healthy: true, version: "1.2.3" })
|
||||
})
|
||||
@@ -25,7 +30,7 @@ describe("checkServerHealth", () => {
|
||||
throw new Error("network")
|
||||
}) as unknown as typeof globalThis.fetch
|
||||
|
||||
const result = await checkServerHealth("http://localhost:4096", fetch)
|
||||
const result = await checkServerHealth(server, fetch)
|
||||
|
||||
expect(result).toEqual({ healthy: false })
|
||||
})
|
||||
@@ -51,7 +56,9 @@ describe("checkServerHealth", () => {
|
||||
)
|
||||
})) as unknown as typeof globalThis.fetch
|
||||
|
||||
const result = await checkServerHealth("http://localhost:4096", fetch, { timeoutMs: 10 }).finally(() => {
|
||||
const result = await checkServerHealth(server, fetch, {
|
||||
timeoutMs: 10,
|
||||
}).finally(() => {
|
||||
if (timeout) Object.defineProperty(AbortSignal, "timeout", timeout)
|
||||
if (!timeout) Reflect.deleteProperty(AbortSignal, "timeout")
|
||||
})
|
||||
@@ -71,7 +78,9 @@ describe("checkServerHealth", () => {
|
||||
}) as unknown as typeof globalThis.fetch
|
||||
|
||||
const abort = new AbortController()
|
||||
await checkServerHealth("http://localhost:4096", fetch, { signal: abort.signal })
|
||||
await checkServerHealth(server, fetch, {
|
||||
signal: abort.signal,
|
||||
})
|
||||
|
||||
expect(signal).toBe(abort.signal)
|
||||
})
|
||||
@@ -87,7 +96,7 @@ describe("checkServerHealth", () => {
|
||||
})
|
||||
}) as unknown as typeof globalThis.fetch
|
||||
|
||||
const result = await checkServerHealth("http://localhost:4096", fetch, {
|
||||
const result = await checkServerHealth(server, fetch, {
|
||||
retryCount: 2,
|
||||
retryDelayMs: 1,
|
||||
})
|
||||
@@ -103,7 +112,7 @@ describe("checkServerHealth", () => {
|
||||
throw new TypeError("network")
|
||||
}) as unknown as typeof globalThis.fetch
|
||||
|
||||
const result = await checkServerHealth("http://localhost:4096", fetch, {
|
||||
const result = await checkServerHealth(server, fetch, {
|
||||
retryCount: 2,
|
||||
retryDelayMs: 1,
|
||||
})
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { createOpencodeClient } from "@opencode-ai/sdk/v2/client"
|
||||
import type { ServerConnection } from "@/context/server"
|
||||
import { createSdkForServer } from "./server"
|
||||
|
||||
export type ServerHealth = { healthy: boolean; version?: string }
|
||||
|
||||
@@ -17,7 +18,10 @@ function timeoutSignal(timeoutMs: number) {
|
||||
const timeout = (AbortSignal as unknown as { timeout?: (ms: number) => AbortSignal }).timeout
|
||||
if (timeout) {
|
||||
try {
|
||||
return { signal: timeout.call(AbortSignal, timeoutMs), clear: undefined as (() => void) | undefined }
|
||||
return {
|
||||
signal: timeout.call(AbortSignal, timeoutMs),
|
||||
clear: undefined as (() => void) | undefined,
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
const controller = new AbortController()
|
||||
@@ -52,7 +56,7 @@ function retryable(error: unknown, signal?: AbortSignal) {
|
||||
}
|
||||
|
||||
export async function checkServerHealth(
|
||||
url: string,
|
||||
server: ServerConnection.HttpBase,
|
||||
fetch: typeof globalThis.fetch,
|
||||
opts?: CheckServerHealthOptions,
|
||||
): Promise<ServerHealth> {
|
||||
@@ -67,8 +71,8 @@ export async function checkServerHealth(
|
||||
.catch(() => ({ healthy: false }))
|
||||
}
|
||||
const attempt = (count: number): Promise<ServerHealth> =>
|
||||
createOpencodeClient({
|
||||
baseUrl: url,
|
||||
createSdkForServer({
|
||||
server,
|
||||
fetch,
|
||||
signal,
|
||||
})
|
||||
|
||||
22
packages/app/src/utils/server.ts
Normal file
22
packages/app/src/utils/server.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { createOpencodeClient } from "@opencode-ai/sdk/v2/client"
|
||||
import type { ServerConnection } from "@/context/server"
|
||||
|
||||
export function createSdkForServer({
|
||||
server,
|
||||
...config
|
||||
}: Omit<NonNullable<Parameters<typeof createOpencodeClient>[0]>, "baseUrl"> & {
|
||||
server: ServerConnection.HttpBase
|
||||
}) {
|
||||
const auth = (() => {
|
||||
if (!server.password) return
|
||||
return {
|
||||
Authorization: `Basic ${btoa(`${server.username ?? "opencode"}:${server.password}`)}`,
|
||||
}
|
||||
})()
|
||||
|
||||
return createOpencodeClient({
|
||||
...config,
|
||||
headers: { ...config.headers, ...auth },
|
||||
baseUrl: server.url,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user