mirror of
https://github.com/garrytan/gbrain.git
synced 2026-07-29 16:39:15 +00:00
feat(doctor): pool_budget check for GBRAIN_MAX_CONNECTIONS (#1794)
computePoolBudgetCheck + checkPoolBudget warn when the parent pool leaves no room for a parallel sync worker under GBRAIN_MAX_CONNECTIONS, pointing at GBRAIN_POOL_SIZE=2. Registered in the ops category set.
This commit is contained in:
@@ -677,6 +677,9 @@ export async function doctorReportRemote(engine: BrainEngine): Promise<DoctorRep
|
||||
// v0.41.19.0 (Issue 5): sync --all consolidation nudge for multi-source brains.
|
||||
checks.push(await checkSyncConsolidation(engine));
|
||||
|
||||
// v0.42.x (#1794, 4A): pool-budget nudge when GBRAIN_MAX_CONNECTIONS is set.
|
||||
checks.push(await checkPoolBudget(engine));
|
||||
|
||||
// v0.42.7 (#1696): link-extraction lag. Strictly SQL (single indexed COUNT),
|
||||
// safe on the thin-client/remote path — remote operators on checkout-less
|
||||
// Postgres brains are exactly who can't otherwise see the extraction backlog.
|
||||
@@ -3271,6 +3274,65 @@ export async function checkSyncConsolidation(engine: BrainEngine): Promise<Check
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* v0.42.x (#1794, 4A) — pure pool-budget check. When `GBRAIN_MAX_CONNECTIONS`
|
||||
* is set (the operator opted into the single-source connection clamp), verify
|
||||
* the parent pool leaves room for at least one parallel worker. If even the
|
||||
* parent pool alone is at/over the budget, sync clamps to serial AND every
|
||||
* other gbrain process competes for the same cap — the operator should lower
|
||||
* `GBRAIN_POOL_SIZE`. Pure so it's unit-testable without env/engine.
|
||||
*/
|
||||
export function computePoolBudgetCheck(
|
||||
maxConnections: number | undefined,
|
||||
parentPool: number,
|
||||
perWorkerPool: number,
|
||||
): Check {
|
||||
if (maxConnections === undefined) {
|
||||
return {
|
||||
name: 'pool_budget',
|
||||
status: 'ok',
|
||||
message: 'GBRAIN_MAX_CONNECTIONS not set — connection budget clamp disabled (default behavior).',
|
||||
};
|
||||
}
|
||||
if (parentPool + perWorkerPool > maxConnections) {
|
||||
return {
|
||||
name: 'pool_budget',
|
||||
status: 'warn',
|
||||
message:
|
||||
`GBRAIN_MAX_CONNECTIONS=${maxConnections} leaves no room for a parallel sync worker ` +
|
||||
`(parent pool ${parentPool} + ${perWorkerPool} per-worker > ${maxConnections}). ` +
|
||||
`Sync will run serial. If you hit EMAXCONNSESSION, lower the parent pool: ` +
|
||||
'`gbrain config` / set GBRAIN_POOL_SIZE=2 (recommended for low-cap poolers like Supabase Supavisor).',
|
||||
};
|
||||
}
|
||||
const maxWorkers = Math.floor((maxConnections - parentPool) / perWorkerPool);
|
||||
return {
|
||||
name: 'pool_budget',
|
||||
status: 'ok',
|
||||
message:
|
||||
`GBRAIN_MAX_CONNECTIONS=${maxConnections}: room for up to ${maxWorkers} parallel sync ` +
|
||||
`worker(s) (parent pool ${parentPool} + ${perWorkerPool} per-worker).`,
|
||||
};
|
||||
}
|
||||
|
||||
/** Thin env/engine wrapper over `computePoolBudgetCheck`. */
|
||||
export async function checkPoolBudget(_engine: BrainEngine): Promise<Check> {
|
||||
try {
|
||||
const { resolveMaxConnections } = await import('../core/sync-concurrency.ts');
|
||||
const { resolvePoolSize } = await import('../core/db.ts');
|
||||
const maxConnections = resolveMaxConnections();
|
||||
const parentPool = resolvePoolSize();
|
||||
const perWorkerPool = Math.min(2, resolvePoolSize(2));
|
||||
return computePoolBudgetCheck(maxConnections, parentPool, perWorkerPool);
|
||||
} catch (err) {
|
||||
return {
|
||||
name: 'pool_budget',
|
||||
status: 'ok',
|
||||
message: `Skipped (${err instanceof Error ? err.message : String(err)})`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* v0.38 — per-source `last_full_cycle_at` freshness check.
|
||||
*
|
||||
|
||||
@@ -136,6 +136,7 @@ export const OPS_CHECK_NAMES: ReadonlySet<string> = new Set([
|
||||
'orphan_clones',
|
||||
'pgbouncer_prepare',
|
||||
'pgvector',
|
||||
'pool_budget',
|
||||
'progressive_batch_audit_health',
|
||||
'queue_health',
|
||||
'reranker_health',
|
||||
|
||||
Reference in New Issue
Block a user