perf: pool de conexiones + frontend optimista (arregla la lentitud)#58
Merged
Conversation
Backend: pool global (psycopg_pool) reusa conexiones → connect por request 1-8s → <0,3s; repos _connect→pool.connection() (mismo API); register_vector/dict_row al configure del pool; lifespan pre-calienta; añade psycopg[pool]. Frontend: OrgProvider usa activeOrgId de localStorage optimista (no bloquea la app en /v2/orgs) + staleTime largo. Multitenancy intacta (claims transaction-local). Aborda las capas 3 y 4 del análisis; 0€. Claude-Session: https://claude.ai/code/session_0198KfgRWvAM8BhiVz24uTok
T1 src/db/pool.py (ConnectionPool singleton, configure=dict_row+register_vector) + psycopg[pool]; T2 los 7 repos + graph/gaps _connect→get_pool().connection() (quita register_vector/row_factory inline, mantiene claims); T3 asgi lifespan pre-calienta; T4 OrgProvider optimista (activeOrgId de localStorage sin bloquear + staleTime). Verificación local=CI. Claude-Session: https://claude.ai/code/session_0198KfgRWvAM8BhiVz24uTok
- requirements.txt: psycopg[binary,pool]==3.3.3 (añade pool extra) - src/db/pool.py: singleton ConnectionPool (min=2/max=10), lazy open, _configure centraliza dict_row + register_vector por conexión nueva - tests/test_db_pool.py: singleton + _configure (TDD RED→GREEN) - no-.env gate: 819 passed, rc=0 Claude-Session: https://claude.ai/code/session_0198KfgRWvAM8BhiVz24uTok
- src/{orgs,certify,jira/integrations}_repository.py: _connect → get_pool().connection()
- src/{graph/service,defects,knowledge,repo_ingest}/repository.py: mismo cambio;
elimina register_vector + row_factory inline (ya los maneja configure del pool);
quita import register_vector
- src/graph/gaps.py: _connect(db_url) → get_pool().connection() (db_url queda por compat)
- tests/test_graph_gaps.py: parcheaba psycopg.connect → ahora parchea get_pool con
_fake_pool(conn_ctx) helper; sin debilitamiento de aserciones
Gate: DATABASE_URL= pytest -m "not integration" → 819 passed, rc=0
Claude-Session: https://claude.ai/code/session_0198KfgRWvAM8BhiVz24uTok
Lee el activeOrgId de localStorage en el primer render (antes de que /v2/orgs resuelva) y lo valida/corrige cuando la lista llega. Agrega staleTime: 5 min para reducir refetch. Test O1 cubre la ruta optimista (pending → stored) y la corrección cuando el id guardado no pertenece a ninguna org (→ orgs[0]). Claude-Session: https://claude.ai/code/session_0198KfgRWvAM8BhiVz24uTok
… + log en lifespan - ActionRepository._connect y XrayConfig._connect migrados a get_pool().connection() (eliminado psycopg.connect directo por petición; row_factory/vector los gestiona el pool) - test_pooled_connection_does_not_leak_claims: test de integración con pool max_size=1 que verifica que set_config transaction-local no se filtra entre checkouts - asgi.py lifespan: except Exception:pass → logging.warning con el exc (no swallow silencioso) Claude-Session: https://claude.ai/code/session_0198KfgRWvAM8BhiVz24uTok
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
El problema
Producción lenta:
/v2/orgs"se quedaba pensando" y con ella toda la app. Análisis: el backend abría una conexión nueva por request (psycopg.connect→ SSL handshake al pooler de Supabase → 1–8 s), y elOrgProvidergateaba toda la app esperando/v2/orgs.Cambios
Backend — pool de conexiones
src/db/pool.py:ConnectionPoolglobal (psycopg_pool), singleton lazy, pre-abre conexiones y las reusa.configurecentralizarow_factory=dict_row+register_vector._connectusaget_pool().connection()(mismowith self._connect() as conn:).asgi.py: lifespan pre-calienta el pool al arranque (con log si falla, no tumba el boot).requirements:psycopg[binary]→psycopg[binary,pool].Frontend — que
/v2/orgsno bloqueeOrgProviderusa elactiveOrgIddelocalStorageen el 1er render (sin esperar a/v2/orgs) → las páginas arrancan ya; valida/corrige al cargar la lista.staleTime5 min.Seguridad (revisado con cuidado — es un pool multi-tenant)
El review final (opus) verificó contra el source de psycopg_pool que los claims
set_config(..., is_local=true)(transaction-local) se limpian por doble mecanismo al devolver la conexión → no fugan entre checkouts. Añadido un test de integración (poolmax_size=1) que lo confirma con BD real: el 2º checkout no ve el claim del 1º. Membership app-layer y bypass RLS del pooler intactos.Plan de pruebas
.env: 819 passed, cov 79.4%, eval_ai 10/10._set_claimssin cambios.Complementos (fuera de este PR)
El pinger (cold start de HF) y
maxDuration=60(ya en main) siguen siendo necesarios; este PR ataca la latencia por-request.https://claude.ai/code/session_0198KfgRWvAM8BhiVz24uTok