๐ Caso 04 โ Python 3.12 resiliente vs legacy#
Implementacion operativa del caso 04 para contrastar retries agresivos contra una variante que contiene la falla.
โฌ ๏ธ Caso 04 ยท โ๏ธ Comparativa de los 7 stacks ยท ๐ Perfil de Python ยท ๐งฌ Todos los perfiles
๐ฏ Que resuelve#
Modela una API de cotizacion que depende de un proveedor externo de carriers:
quote-legacyrepite timeouts varias veces y amplifica la carga saliente;quote-resilientusa timeout corto, backoff exponencial, circuit breaker y fallback cacheado.
๐ผ Por que importa#
Este caso deja visible un patron muy real: una dependencia lenta no solo agrega latencia, tambien puede degradar al servicio llamador cuando los retries no tienen limites sanos. El efecto cascada es la regla, no la excepcion.
๐ฌ Analisis Tecnico de la Implementacion (Python)#
El control de tiempo en Python sobre I/O simulado con time.sleep() expone la diferencia entre una politica de reintentos agresiva y una con backoff y circuit breaker.
- Punto Critico (
legacy): La funcioncall_provider_legacy()ejecuta un buclefor attempt in range(max_attempts)conmax_attempts=4ytimeout_ms=360. En cada iteracion llama atime.sleep(timeout_ms / 1000)sin espera entre intentos (backoff_base_ms=0). Bajo un escenarioprovider_down, el proceso queda bloqueado durante4 * 0.36 = 1.44segundos minimos por request, multiplicando la presion sobre el proveedor sin ninguna posibilidad de recuperacion. ElThreadingHTTPServermantiene un hilo ocupado por ese tiempo completo, agotando el pool de workers bajo carga concurrente. - Resguardo Nativo (
resilient): Implementa Exponential Backoff con Jitter en la funcioncalculate_backoff_ms():base_ms * (2 ** max(0, attempt - 1)) + random.randint(15, 45). El jitter aleatorio desfasa los picos de reintento cuando multiples clientes fallan simultaneamente. El Circuit Breaker se evalua comparandotime.time()conprovider["opened_until"]antes de iniciar cualquier I/O: si el circuito esta abierto, la funcion retorna inmediatamente con elfallback_quotecacheado del ultimo exito, eliminando completamente la latencia de espera. El estado del circuito (consecutive_failures,opened_until,fallback_quote) se persiste en JSON bajotempfile.gettempdir()para sobrevivir reinicios del servidor.
๐งฑ Servicio#
appโ API Python 3.12 con escenarios de proveedor estable, lento, caido o intermitente.
๐ Arranque#
docker compose -f compose.yml up -d --buildPuerto local: 834 (modo aislado, ver opciones abajo).
Como consumir (dos opciones)#
Hub Python (recomendado, 8200 en compose.python.yml): este caso queda servido en http://localhost:8200/04/... junto a los otros 11 casos.
Modo aislado (834 en este compose.yml): levanta solo este caso, util cuando la medicion necesita procesar limpio (sin otros casos compartiendo runtime).
๐ Endpoints#
curl http://localhost:8200/04/
curl http://localhost:8200/04/health
curl "http://localhost:8200/04/quote-legacy?scenario=provider_down&customer_id=42&items=3"
curl "http://localhost:8200/04/quote-resilient?scenario=provider_down&customer_id=42&items=3"
curl http://localhost:8200/04/dependency/state
curl "http://localhost:8200/04/incidents?limit=10"
curl http://localhost:8200/04/diagnostics/summary
curl http://localhost:8200/04/metrics
curl http://localhost:8200/04/metrics-prometheus
curl http://localhost:8200/04/reset-lab๐งช Escenarios utiles#
provider_downโ ideal para ver tormenta de retries en legacy y fallback en resilient.flaky_providerโ muestra retry util versus retry agresivo.burst_then_recoverโ permite ver recuperacion parcial con distinto costo de backoff.slow_providerโ enfatiza la necesidad de deadlines explicitos en el timeout.
๐งญ Que observar#
- cuantos intentos y retries hace cada modo por request;
- si el circuito se abre y evita seguir golpeando la dependencia;
- cuando aparece respuesta degradada con fallback en vez de cascada de fallas;
- como cambia la latencia total entre
legacyyresilienten el mismo escenario.
โ๏ธ Nota de honestidad#
No reemplaza una integracion real ni una malla de servicios. Si reproduce el comportamiento operativo que importa aqui: timeouts, retries, circuit breaker, fallback y el costo de una mala postura de resiliencia.