mirror of
https://github.com/garrytan/gstack.git
synced 2026-07-19 05:57:37 +02:00
fix(gbrain): classify PGLite connect locks
This commit is contained in:
@@ -19,6 +19,8 @@
|
||||
* Broken-config → config exists but `gbrain sources list` fails with config parse error
|
||||
* (or any non-recognized error — defensive default per codex #8).
|
||||
* Broken-db → config exists, DB unreachable per stderr classification.
|
||||
* Engine-locked → PGLite probe hit gbrain's own connect timeout, usually
|
||||
* because another `gbrain serve` process owns the embedded DB.
|
||||
* Timeout → probe exceeded GSTACK_GBRAIN_PROBE_TIMEOUT_MS (default 15s) with no
|
||||
* recognized error — engine is likely healthy but slow (e.g. a cold
|
||||
* pooler connection, #1964). Consumers treat this as usable.
|
||||
@@ -47,6 +49,7 @@ export type LocalEngineStatus =
|
||||
| "missing-config"
|
||||
| "broken-config"
|
||||
| "broken-db"
|
||||
| "engine-locked"
|
||||
| "timeout";
|
||||
|
||||
export interface ClassifyOptions {
|
||||
@@ -118,6 +121,15 @@ function gbrainConfigPath(env?: NodeJS.ProcessEnv): string {
|
||||
return join(gbrainHome, "config.json");
|
||||
}
|
||||
|
||||
function configuredEngine(env?: NodeJS.ProcessEnv): "pglite" | "postgres" | null {
|
||||
try {
|
||||
const parsed = JSON.parse(readFileSync(gbrainConfigPath(env), "utf-8")) as { engine?: string };
|
||||
return parsed.engine === "pglite" || parsed.engine === "postgres" ? parsed.engine : null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function hashPath(p: string): string {
|
||||
return createHash("sha256").update(p).digest("hex").slice(0, 16);
|
||||
}
|
||||
@@ -281,6 +293,7 @@ function freshClassify(env?: NodeJS.ProcessEnv): LocalEngineStatus {
|
||||
stderr?: Buffer | string;
|
||||
killed?: boolean;
|
||||
signal?: NodeJS.Signals | null;
|
||||
status?: number | null;
|
||||
};
|
||||
const stderr = (e.stderr ? e.stderr.toString() : "") || "";
|
||||
|
||||
@@ -292,6 +305,14 @@ function freshClassify(env?: NodeJS.ProcessEnv): LocalEngineStatus {
|
||||
if (stderr.includes("Cannot connect to database")) return "broken-db";
|
||||
if (stderr.includes("config.json")) return "broken-config";
|
||||
|
||||
// PGLite is single-process. A long-lived `gbrain serve` can own the
|
||||
// embedded database, causing the CLI to finish with its own exit 124 and
|
||||
// "connect timed out" message. This is neither our watchdog timeout nor
|
||||
// evidence that the valid config is malformed (#2194).
|
||||
if (stderr.includes("connect timed out") || e.status === 124) {
|
||||
return configuredEngine(env) === "pglite" ? "engine-locked" : "broken-db";
|
||||
}
|
||||
|
||||
// Probe killed by the timeout with no recognized error: the engine is
|
||||
// most likely healthy but slow (cold pooler connections measured at
|
||||
// 6.9-10.7s in #1964). Don't tell the user their config is malformed.
|
||||
|
||||
Reference in New Issue
Block a user