fix: 非阻塞回退 Workbench API 调优配置
This commit is contained in:
@@ -8,10 +8,20 @@ const kafkaEventBridge = runtime.mode === "agentrun-native" ? startHwlabKafkaEve
|
||||
const app = createWorkbenchHttpApp({ dispatch: runtime.dispatch, snapshot: runtime.application.snapshot?.bind(runtime.application), authorization: process.env.WORKBENCH_API_AUTHORIZATION, mode: runtime.mode, kafkaEventBridge, close: async () => { await kafkaEventBridge?.stop?.(); await runtime.close(); } });
|
||||
const host = process.env.WORKBENCH_API_HOST || "0.0.0.0";
|
||||
const port = positivePort(process.env.WORKBENCH_API_PORT || process.env.PORT, 6677);
|
||||
const idleTimeout = positiveInteger(process.env.WORKBENCH_API_IDLE_TIMEOUT_SECONDS, "WORKBENCH_API_IDLE_TIMEOUT_SECONDS");
|
||||
const idleTimeoutConfig = positiveIntegerOrDefault(process.env.WORKBENCH_API_IDLE_TIMEOUT_SECONDS, 60);
|
||||
const idleTimeout = idleTimeoutConfig.value;
|
||||
if (idleTimeoutConfig.warningReason) {
|
||||
process.stderr.write(`${JSON.stringify({ event: "hwlab.config.warning", code: "workbench_api_idle_timeout_defaulted", configKey: "WORKBENCH_API_IDLE_TIMEOUT_SECONDS", reason: idleTimeoutConfig.warningReason, defaultValue: idleTimeout, blocking: false, valuesPrinted: false })}\n`);
|
||||
}
|
||||
const server = Bun.serve({ hostname: host, port, idleTimeout, fetch: (request) => app.fetch(request) });
|
||||
process.stdout.write(`${JSON.stringify({ serviceId: "hwlab-workbench-api", status: "listening", mode: runtime.mode, host, port: server.port, idleTimeout, temporalNamespace: runtime.temporalNamespace, taskQueue: runtime.taskQueue })}\n`);
|
||||
for (const signal of ["SIGINT", "SIGTERM"] as const) process.once(signal, async () => { server.stop(true); await app.close(); process.exit(0); });
|
||||
|
||||
function positivePort(value: string | undefined, fallback: number) { const parsed = Number.parseInt(String(value ?? fallback), 10); if (!Number.isInteger(parsed) || parsed < 1 || parsed > 65535) throw new Error("WORKBENCH_API_PORT must be a valid port"); return parsed; }
|
||||
function positiveInteger(value: string | undefined, name: string) { const parsed = Number.parseInt(String(value ?? ""), 10); if (!Number.isSafeInteger(parsed) || parsed < 1) throw new Error(`${name} must be a positive integer`); return parsed; }
|
||||
function positiveIntegerOrDefault(value: string | undefined, fallback: number) {
|
||||
const raw = String(value ?? "").trim();
|
||||
if (!raw) return { value: fallback, warningReason: "missing" };
|
||||
const parsed = Number.parseInt(raw, 10);
|
||||
if (!Number.isSafeInteger(parsed) || parsed < 1 || String(parsed) !== raw) return { value: fallback, warningReason: "invalid-positive-integer" };
|
||||
return { value: parsed, warningReason: null };
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import { externalPostgresConfigForLane, externalPostgresManifest, opencodeEgress
|
||||
|
||||
import { CLOUD_CORE_MIGRATIONS, CLOUD_TRANSACTIONAL_REALTIME_MIGRATION_ID } from "../internal/db/schema.ts";
|
||||
|
||||
test("v03 Workbench API declares its required Bun idle timeout in owning YAML", async () => {
|
||||
test("v03 Workbench API declares its preferred Bun idle timeout in owning YAML", async () => {
|
||||
const deploy = parseYaml(await readFile("deploy/deploy.yaml", "utf8"));
|
||||
const service = deploy.lanes.v03.services.find((item: { serviceId?: string }) => item.serviceId === "hwlab-workbench-api");
|
||||
assert.ok(service, "missing v03 hwlab-workbench-api service declaration");
|
||||
|
||||
@@ -20,8 +20,7 @@ try {
|
||||
const nativeEnv = {
|
||||
...process.env,
|
||||
WORKBENCH_MODE: "native-test",
|
||||
WORKBENCH_NATIVE_STATE_FILE: path.join(stateDir, "state.json"),
|
||||
WORKBENCH_API_IDLE_TIMEOUT_SECONDS: "60"
|
||||
WORKBENCH_NATIVE_STATE_FILE: path.join(stateDir, "state.json")
|
||||
};
|
||||
const api = start(["bun", "cmd/hwlab-workbench-api/main.ts"], {
|
||||
...nativeEnv,
|
||||
@@ -30,6 +29,9 @@ try {
|
||||
}, "api");
|
||||
children.push(api);
|
||||
await waitFor(`${apiUrl}/health/ready`);
|
||||
if (!logs.some((item) => item.service === "api" && item.stream === "stderr" && item.line.includes('"code":"workbench_api_idle_timeout_defaulted"') && item.line.includes('"blocking":false'))) {
|
||||
throw new Error("missing non-blocking idle timeout fallback warning");
|
||||
}
|
||||
|
||||
const web = start(["bun", "run", "workbench:web:dev"], { ...process.env, WORKBENCH_WEB_PORT: String(webPort) }, "web");
|
||||
children.push(web);
|
||||
|
||||
Reference in New Issue
Block a user