🧪 Problem-Driven Systems Lab
🚰 Caso 14 · Rendimiento

Agotamiento del pool de conexiones

Un pool chico, sin timeout de adquisicion y con fugas en el camino de excepcion deja de dar conexiones para siempre.

OPERATIVO 🐘 PHP🐍 Python🟢 Node.js☕ Java🔵 .NET🐹 Go🦀 Rust

📈 Que cambia para el negocio

Evita indisponibilidades progresivas que tienen al reinicio como unico remedio, y dimensiona el pool con una formula en vez de con intuicion.

💼 Que demuestra tecnicamente

Muestra que un pool vacio y uno ocupado se ven igual en el dashboard, y que cuando el p99 desaparece del grafico la mala noticia es peor que una latencia alta.

✅ Evidencia que deja

  • Contrasta /pool-leaky y /pool-managed sobre la misma carga con leaked = acquired - released como metrica central.
  • Hace visible hung, failed_timeout y pool_available_after: si al terminar el pool no volvio a su tamaño, hubo fuga.
  • Expone littles_law con el tamaño de pool recomendado calculado desde el throughput medido, no estimado.

👀 Que mirar al ejecutarlo

  • Si leaked es exactamente el numero de fallos en la variante leaky y 0 en la corregida.
  • Si hung crece hasta consumir el resto de la carga: es el pool agotado en vivo.
  • Si failed_timeout reemplaza a hung en la variante corregida: el mismo problema de capacidad, pero contable.
Honestidad: Las conexiones son objetos en memoria, no sockets contra una base real, y el tiempo de query es un sleep. Eso ultimo es deliberado y mas fiel que quemar CPU: una conexion se retiene mientras se espera a la red. En PHP las N requests se recorren en secuencia porque el servidor embebido es de un solo proceso.

Como esta resuelto en cada stack

Devolucion garantizada con la primitiva de cada runtime: finally en PHP, @contextmanager sobre queue.Queue en Python, finally con AbortSignal.timeout en Node, try-with-resources sobre ArrayBlockingQueue en Java, using var con SemaphoreSlim.WaitAsync en .NET, canal bufferizado como pool con select y defer en Go, impl Drop en Rust — donde fugar exige escribir mem::forget a proposito

StackHealth check localComposeDetalle
🐘 PHP 8.3http://localhost:8100/14/healthcompose.root.ymlREADME del stack
🐍 Python 3.12http://localhost:8200/14/healthcompose.python.ymlREADME del stack
🟢 Node.js 22http://localhost:8300/14/healthcompose.nodejs.ymlREADME del stack
☕ Java 21http://localhost:8400/14/healthcompose.java.ymlREADME del stack
🔵 .NET 8http://localhost:8500/14/healthcompose.dotnet.ymlREADME del stack
🐹 Go 1.23http://localhost:8600/14/healthcompose.go.ymlREADME del stack
🦀 Rust 1.83http://localhost:8700/14/healthcompose.rust.ymlREADME del stack

El expediente completo

El caso no empieza en el codigo: empieza en el sintoma y termina en el postmortem.

← Caso 13Caso 15 →