diff --git a/src/commands/doctor.ts b/src/commands/doctor.ts index 6441ab3d3..b463cd1c8 100644 --- a/src/commands/doctor.ts +++ b/src/commands/doctor.ts @@ -677,6 +677,9 @@ export async function doctorReportRemote(engine: BrainEngine): Promise 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 { + 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. * diff --git a/src/core/doctor-categories.ts b/src/core/doctor-categories.ts index 81dfedd5b..0941ce495 100644 --- a/src/core/doctor-categories.ts +++ b/src/core/doctor-categories.ts @@ -136,6 +136,7 @@ export const OPS_CHECK_NAMES: ReadonlySet = new Set([ 'orphan_clones', 'pgbouncer_prepare', 'pgvector', + 'pool_budget', 'progressive_batch_audit_health', 'queue_health', 'reranker_health',