Commit History
-
[NOTICKET][DB] perf(query): DB2 - pooled engine cache for user DBs
Rifqi Hafizuddin +1: Claude Opus 4.8DbExecutor built a fresh engine and disposed it on every query, paying a full TCP+TLS+auth handshake per call (~6-8s measured, dominating slow-path latency). engine_scope's connect-once-dispose is right for ingestion, wrong for the query path. - New UserEngineCache (src/database_client/engine.py): process-wide cache of pooled engines keyed by client_id + a hash of the decrypted creds (rotation auto- invalidates the key). Bounded LRU (50) + 600s idle TTL; pool_pre_ping + pool_recycle=300; small pool (1 + 2 overflow). invalidate(client_id) disposes eagerly. Scope: postgres/supabase only; other db_types keep the legacy per-call path, so nothing regresses. - DbExecutor._run_sync reuses the warm connection (no per-query SET, no dispose). - Read-only + statement_timeout moved from libpq startup `options` to a per- connection `connect` event: Neon's transaction pooler rejects default_transaction_read_only as a startup parameter (caught in a live run) but accepts it as a SET. …4c911cb