Diseno experimento HA 01 - martin-hendricks/MISO-PROYECTO-FINAL-SOLVENTA GitHub Wiki

Diseño de experimento

Módulo 5 — EDA Maestría en Ingeniería de Software — MISW4501 Arquitectura de Software Caso de estudio: Solventa — plataforma insurtech Versión: 1.0

Documento complementario: la implementación detallada (Docker, contrato del proveedor, código fuente, scripts de carga y protocolo de ejecución) se encuentra en Guia_Tecnica_HA-01.md.


1. Ficha del experimento

Campo Detalle
Título del experimento Caché con actualización oportunista y valor de respaldo para proteger el presupuesto de latencia de la cotización embebida ante un proveedor de Open Finance degradado
Propósito del experimento Evaluar si la distribución de componentes propuesta —:MsCotización → :CacheOF → :AdaptadorOF → proveedor externo, con la llamada al adaptador fuera del camino bloqueante— permite cumplir EC-LAT-01 (p95 ≤ 250 ms) y EC-LAT-02 (p99 ≤ 500 ms) tanto con el proveedor sano como degradado (EC-LAT-09), y determinar cuál es el nivel mínimo de desacople que lo satisface. El montaje no incluye el :ApiGateway, de modo que los umbrales se trasladan al servicio descontando el presupuesto de borde (Anexo G).
Resultados esperados Se espera que la llamada síncrona bloqueante al proveedor no alcance el umbral cuando este se degrada, que la caché con lectura bloqueante en fallo lo alcance solo si la tasa de acierto es muy alta, y que la caché con actualización oportunista lo alcance de forma estable e independiente del estado del proveedor. El experimento debe cuantificar el costo de esa independencia en dos dimensiones: la frescura del dato con que se tarifica y la proporción de cotizaciones resueltas con valor de respaldo. Se espera además confirmar el resultado contraintuitivo previsto por el equipo: el camino degradado resulta más rápido que el camino frío con proveedor sano.
Elementos de arquitectura involucrados ASR asociados: EC-LAT-01 y EC-LAT-02 — Latencia, prioridad (A,A); EC-LAT-09 — Latencia con dependencia degradada, prioridad (A,A). Restricciones de presupuesto: EC-LAT-07 (≤ 120 ms por dependencia externa) y EC-LAT-08 (timeout duro de 700 ms).
Historia de arquitectura: HA-01.
Vistas y modelos: Vista funcional (:MsCotización, :MotorRaiting, :CacheOF, :AdaptadorOF); Vista de despliegue (ElastiCache Redis y grupo de escalado de cotización); Vista de información (§1.4.4 valor de respaldo, §1.4.3 estrategia de replicación de la Hoja de trabajo semana 5).
Correspondencia con el diagrama de componentes: el montaje no introduce componentes nuevos. Cada pieza corresponde a un «component» o «datastore» ya publicado en §1.2, salvo el inyector de fallas y el doble del proveedor, que son instrumentación y se declaran como tales.
Puntos de sensibilidad que se desean probar: grado de bloqueo de la dependencia externa, tasa de acierto de la caché, estado del proveedor, política del interruptor y tasa de llegada.
Esfuerzo estimado Tiempo: 1 semana — 40 horas
Horas hombre: 10 horas/hombre (4 integrantes)
Menor que HA-08 porque se reutiliza el montaje de contenedores, el stack de observabilidad y el protocolo de corridas ya construidos.

Recursos requeridos

  • Lenguaje y framework: Python 3.12, FastAPI, Uvicorn (uvloop, httptools)
  • Contenerización: Docker y Docker Compose V2 (extiende el docker-compose.yml de HA-08)
  • Almacenamiento: Redis 7 (:CacheOF), PostgreSQL 16 (catálogo de producto y reglas de tarifa)
  • Cliente HTTP asíncrono: httpx con límites de conexión explícitos por proveedor
  • Doble del proveedor de Open Finance: servicio FastAPI que devuelve el contrato real de Open Finance con una distribución de latencia de aplicación configurable (no un valor fijo)
  • Inyección de fallas de red: Toxiproxy, interpuesto entre :AdaptadorOF y el doble, para degradación a nivel de conexión TCP
  • Librerías: httpx, redis-py (asyncio), asyncpg, orjson, pydantic, prometheus-client
  • Generación de carga: k6 con ejecutor de tasa de llegada
  • Observabilidad: Prometheus, Grafana
  • Hardware: estación de desarrollo con mínimo 16 GB de RAM, 4 núcleos y 10 GB de disco libre. El dataset es mucho menor que el de HA-08: no hay millón de registros, sino un conjunto de perfiles de Open Finance del tamaño del universo de clientes simulado.

2. Hipótesis de diseño

Enunciado

Si :MsCotización resuelve el perfil de Open Finance leyendo :CacheOF y trata la invocación de :AdaptadorOF como una actualización oportunista —abandonando la espera al agotar el presupuesto por dependencia de 120 ms (EC-LAT-07) y resolviendo con el último valor conocido o con un valor por defecto—, mientras :AdaptadorOF conserva su timeout duro de 700 ms (EC-LAT-08) con circuit breaker y aislamiento de recursos por proveedor,

entonces la cotización embebida alcanzará un p95 ≤ 225 ms y un p99 ≤ 475 ms medidos en el servicio —equivalentes a 250 ms y 500 ms extremo a extremo una vez sumado el presupuesto de borde del Anexo G— con el proveedor sano y también con el proveedor degradado o caído,

aceptando como contrapartida que una fracción acotada de las cotizaciones se tarifique con señales menos frescas o con valores por defecto, que esa fracción quede trazada para actuaría, y que un conjunto reducido de peticiones se sacrifique durante la apertura del interruptor.

Campo Detalle
Historia de arquitectura asociada HA-01 — Protección del presupuesto de latencia de la cotización embebida
Escenarios de calidad EC-LAT-01 y EC-LAT-02 (operación normal y horario pico), EC-LAT-09 (dependencia degradada). Restricciones: EC-LAT-07, EC-LAT-08
Nivel de incertidumbre Alto. La separación de los dos timeouts en componentes distintos es una lectura del equipo, no una prescripción del enunciado: el caso da ambos números sin decir a quién pertenecen. Se desconoce (a) cuántas peticiones se sacrifican antes de que el interruptor abra y si ese conjunto rompe el p99, (b) si el umbral por conteo abre a tiempo con tráfico bajo, (c) si las llamadas abandonadas por :MsCotización agotan el pool de :AdaptadorOF bajo carga, y (d) qué tasa de acierto de caché es necesaria para sostener el escenario. El costo de equivocarse es alto: si el diseño no se sostiene, la cotización embebida —el journey que define la propuesta de valor de Solventa— incumple su ASR frente a un proveedor que Solventa no controla.

Puntos de sensibilidad

# Punto de sensibilidad ¿Qué probar?
1 Grado de bloqueo de la dependencia externa. Es la decisión arquitectónica central: cuánto puede el camino crítico depender de un tercero impredecible. Variar la estrategia de resolución del perfil en tres niveles: A invocación síncrona bloqueante al adaptador en cada cotización, sin caché; B caché con lectura bloqueante en fallo (cache-aside clásico: el fallo espera al proveedor); C caché con actualización oportunista y valor de respaldo (el diseño propuesto: la respuesta nunca espera al proveedor).
2 Estado del proveedor externo. EC-LAT-09 exige cumplir el umbral con la dependencia degradada, no solo en condiciones ideales. Cinco estados, más la transición de recuperación. Ver el modelo de fallas del Anexo A: sano, lento, degradado, sin respuesta (acepta la conexión y nunca contesta) y caído (conexión rechazada). El estado sin respuesta es el más hostil y el que realmente pone a prueba el pool del adaptador.
3 Tasa de acierto de la caché. Es la variable que decide si el camino frío define o no el percentil. El diseño se sostiene solo por encima de cierto umbral, y ese umbral hoy no está cuantificado. Preparar el conjunto de claves consultadas para producir tasas de acierto de 99 %, 96 %, 90 % y 50 %, midiendo el p95 y el p99 en cada nivel para localizar el punto de quiebre.
4 Política del circuit breaker. Un umbral por conteo abre rápido con tráfico alto y tarde con tráfico bajo; en el segundo caso las peticiones sacrificadas pueden superar el 1 % de la ventana y romper el p99. Comparar umbral por conteo (N fallos consecutivos) contra umbral por tasa sobre ventana deslizante, en dos niveles de tráfico: alto (200 sol/s) y bajo (10 sol/s).
5 Concurrencia sobre la misma clave (estampida). Varias peticiones concurrentes con fallo sobre el mismo perfil dispararían N invocaciones idénticas al proveedor justo cuando más duele. Brazo adicional C' = C más coalescencia de peticiones (single-flight), midiendo invocaciones al proveedor por fallo de caché y saturación del pool del adaptador.

Sub-hipótesis verificables

ID Enunciado Punto de sensibilidad Brazos
HD-01.1 Con el proveedor sano, los tres brazos cumplen p95 ≤ 225 ms 1, 2 A, B, C
HD-01.2 Con el proveedor degradado, solo el brazo C cumple p95 ≤ 225 ms y p99 ≤ 475 ms 1, 2 A, B, C
HD-01.3 En el brazo C, el camino degradado es más rápido que el camino frío con proveedor sano 1, 2 C
HD-01.4 El brazo C sostiene el umbral con tasa de acierto ≥ 96 %; por debajo de ese valor el p99 se degrada 3 B, C
HD-01.5 Las peticiones sacrificadas hasta la apertura del interruptor son < 1 % de la ventana con tráfico alto 4 C
HD-01.6 Con tráfico bajo, el umbral por conteo no mantiene las sacrificadas bajo el 1 %, y el umbral por tasa sí 4 C
HD-01.7 Sin coalescencia, un fallo concurrente sobre la misma clave produce más de una invocación al proveedor y satura el pool del adaptador antes que con coalescencia 5 C, C'
HD-01.8 Al recuperarse el proveedor, el interruptor cierra y la proporción con respaldo vuelve por debajo del 5 % en ≤ 60 s, sin producir una estampida de invocaciones 2, 5 C, C'

Nota metodológica. HD-01.6 es deliberadamente refutable en su forma afirmativa. Si el umbral por conteo resulta suficiente también con tráfico bajo, el equipo se ahorra una complejidad; si no, tiene evidencia para justificarla. En ambos casos el experimento decide algo.


3. Estilos de arquitectura asociados al experimento

Estilo de arquitectura asociado al experimento Análisis (atributos de calidad que favorece y desfavorece)
Llamada-retorno sincrónico (N-niveles) Favorece:
• Baja latencia interna y consistencia inmediata en el journey de venta
• Simplicidad de razonamiento y de depuración

Desfavorece:
• Acoplamiento temporal con el colaborador
• Propagación de la latencia y de la falla del tercero al camino crítico
Capas + adaptadores (anticorrupción) Favorece:
• Modificabilidad e integrabilidad ante el cambio de proveedor
• Punto único donde alojar timeout, interruptor y aislamiento de recursos

Desfavorece:
• Una indirección más por llamada
• Riesgo de que el adaptador se vuelva cuello de botella si no se le acota el pool
Microservicios (contexto general de Solventa) Favorece:
• Escalamiento selectivo de :MsCotización según la curva de campaña de un socio
• Modificabilidad

Desfavorece:
• Latencia extremo a extremo por los saltos de borde
• Consistencia distribuida

Precisión sobre el origen del costo de latencia. A diferencia de HA-08 —donde el costo provenía de componer el estado sobre cinco entidades normalizadas—, aquí el costo es externo y ajeno al control de Solventa: proviene de la latencia y la variabilidad del proveedor de Open Finance. Ningún estilo interno lo elimina; lo único que la arquitectura puede hacer es sacarlo del camino bloqueante. Ese es el objeto exacto del experimento, y la razón por la que el brazo A no es un hombre de paja sino la implementación que cualquier equipo escribiría primero.


4. Tácticas de arquitectura asociadas al experimento

Táctica de arquitectura asociada al experimento Descripción
Múltiples copias de datos :CacheOF conserva una copia local del perfil de Open Finance con su marca de tiempo. Es la táctica que la wiki ya declara para EC-LAT-09, y la que este experimento pone a prueba. La copia acorta el camino de acceso a costa de introducir una ventana de desactualización que debe medirse, no suponerse.
Incrementar la latencia de los recursos El presupuesto por dependencia de 120 ms es un límite explícito sobre cuánto puede esperar el camino crítico. Al agotarse, :MsCotización abandona la espera en lugar de propagar el retraso del tercero.
Limitar la respuesta a los eventos La actualización del perfil se ejecuta fuera de la respuesta al socio: la invocación al adaptador continúa en segundo plano y su resultado sirve para repoblar la caché, no para responder.
Detección de fallas: temporizador El timeout duro de 700 ms en :AdaptadorOF (EC-LAT-08) es el detector que alimenta al circuit breaker.
Recuperación: degradación elegante Ante la ausencia de perfil fresco, :MsCotización tarifica con el último valor conocido o con el valor por defecto del ramo, y marca la cotización como resuelta con respaldo para trazabilidad actuarial.
Aislamiento de recursos (bulkhead) Pool de conexiones y de trabajo dedicado por proveedor en :AdaptadorOF, de modo que las llamadas abandonadas no agoten los recursos del resto del servicio. Es la táctica que hace viable abandonar a los 120 ms sin efectos colaterales.

5. Listado de componentes involucrados en el experimento

Componente Propósito y comportamiento esperado Tecnología asociada
API de Cotización (:MsCotización) Expone el recurso de cotización embebida. Implementa los cuatro brazos sobre el mismo binario, seleccionables por configuración, de modo que la estrategia de resolución del perfil sea la única variable que cambie entre corridas. Aplica el presupuesto por dependencia, decide entre perfil fresco, último valor conocido y valor por defecto, y marca la respuesta con el origen y la edad del dato usado. Python, FastAPI, Uvicorn, httpx, redis-py, orjson
Motor de Tarifa (:MotorRaiting) Calcula la prima a partir del perfil recibido y del conjunto de reglas vigente. Se implementa con un costo de cómputo fijo y calibrado (~60 ms) para que sea una constante entre brazos y no una fuente de variación. Debe aceptar perfiles incompletos y reflejar la incertidumbre en el resultado. Python, reglas versionadas en memoria, asyncpg para cargar el conjunto de reglas al arranque
Caché de Perfil de Open Finance (:CacheOF) Almacena el perfil por cliente con su marca de tiempo de obtención, bajo política de expiración por fuente. Sirve el último valor conocido incluso vencido cuando el proveedor no responde: la expiración marca cuándo conviene refrescar, no cuándo dejar de servir. Esta distinción es una decisión de diseño y una de las cosas que el experimento debe validar. Redis 7, política allkeys-lru
Adaptador de Open Finance (:AdaptadorOF) Traduce del esquema del proveedor al modelo canónico de señales. Aloja el timeout duro de 700 ms, el circuit breaker con sus tres estados y el pool dedicado por proveedor. Expone como métricas el estado del interruptor, las conexiones en vuelo y el tiempo hasta la apertura. Python, httpx con límites de conexión, interruptor implementado en el propio adaptador para poder instrumentar sus transiciones
Doble del Proveedor de Open Finance (instrumentación, no arquitectura) Sustituye al «External» :OpenFinance del modelo de componentes. Devuelve la forma real del contrato de Open Finance para que el costo de deserialización en el adaptador sea representativo, y aplica una latencia de aplicación muestreada de una distribución log-normal con cola larga, no un valor constante. Es sin estado y determinista bajo semilla fija, de modo que dos repeticiones sean comparables. Corre con límites de recursos propios y su saturación se verifica antes de cada corrida. Python, FastAPI, numpy para el muestreo
Inyector de Fallas de Red (instrumentación, no arquitectura) Se interpone entre el adaptador y el doble para degradar la conexión, no la aplicación: latencia de red, corte de conexión, rechazo y agujero negro. Se modifica en caliente por su API de administración, sin reiniciar el montaje, condición necesaria para recorrer los cinco estados dentro de una misma corrida. Toxiproxy

Los dos últimos componentes no existen en el modelo de arquitectura y no deben aparecer en él. Son el banco de pruebas. Se declaran aquí para que la trazabilidad entre el experimento y el diagrama de componentes sea explícita y no quede a interpretación del lector.


6. Listado de conectores involucrados en el experimento

Conector Comportamiento deseado en el experimento Tecnología asociada
Conector HTTP de cotización El generador de carga emite solicitudes contra el recurso de cotización a una tasa de llegada fija, de modo que la degradación del servicio no reduzca automáticamente la carga y enmascare el percentil. Registra la latencia extremo a extremo por solicitud y etiqueta cada una con el brazo, el estado del proveedor y el nivel de acierto configurado. Cliente: k6 con ejecutor de tasa de llegada. Servidor: Uvicorn sobre ASGI.
Conector de acceso a la caché Lectura por clave del perfil, devolviendo valor y marca de tiempo. En el brazo C la escritura ocurre fuera del camino de respuesta, alimentada por el resultado de la actualización oportunista. redis-py en modo asíncrono sobre Redis 7.
Conector de invocación al proveedor (brazo A) Invocación bloqueante en cada cotización, sin caché y sin presupuesto de abandono: el camino crítico espera lo que el proveedor tarde, hasta el timeout duro. Es la línea base y representa la implementación que se escribiría sin la táctica bajo estudio. httpx asíncrono con timeout de 700 ms.
Conector de invocación bloqueante en fallo (brazo B) Cache-aside clásico: ante un acierto responde de inmediato; ante un fallo invoca al proveedor y espera el resultado antes de responder. Aísla el efecto de la caché del efecto del desacople, que es la distinción que el experimento debe demostrar. httpx asíncrono, misma configuración de timeout.
Conector de actualización oportunista (brazos C y C') La invocación al proveedor se lanza con un presupuesto de 120 ms; al agotarse, la respuesta se resuelve con el último valor conocido o con el valor por defecto y la invocación continúa en segundo plano hasta su timeout duro, repoblando la caché si llega a completarse. El circuit breaker corta las invocaciones mientras esté abierto. En C' se añade coalescencia por clave. httpx con pool dedicado, asyncio.timeout para el presupuesto, tarea en segundo plano para el refresco, coalescencia por clave con asyncio.Future compartido.
Conector de inyección de fallas Permite alterar la latencia y la disponibilidad del proveedor sin reiniciar el montaje, condición necesaria para que los cuatro estados del proveedor se recorran dentro de una misma corrida y sean comparables sin efecto de calentamiento. Toxiproxy con API de administración.
Conector de telemetría La API y el adaptador exponen métricas que Prometheus recolecta periódicamente; el generador de carga las envía por escritura remota al mismo Prometheus, de modo que latencia de cliente, latencia interna, estado del interruptor y saturación del pool queden en la misma línea de tiempo. prometheus-client, Prometheus, Grafana.

7. Tecnología asociada con el experimento

Tecnología asociada con el experimento Selección Justificación
Lenguajes de programación Python 3.12 Alineado con el stack del equipo, con el resto de Solventa y con el experimento HA-08, lo que permite reutilizar montaje y protocolo. Su modelo asíncrono es indispensable para representar la actualización oportunista: la tarea de refresco debe seguir viva después de que la respuesta ya salió.
Frameworks de desarrollo FastAPI + Uvicorn (uvloop, httptools) Framework ASGI nativo asíncrono. Es requisito para el brazo C: un servidor síncrono no puede continuar una invocación en segundo plano después de responder sin bloquear un hilo del pool, lo que falsearía la comparación.
Cliente HTTP httpx en modo asíncrono, con limits explícitos por proveedor Permite fijar el tamaño del pool por destino, que es la implementación concreta del bulkhead, y separar el presupuesto de la petición del timeout de la conexión. Un cliente sin límites por destino haría imposible medir HD-01.7.
circuit breaker Implementación propia dentro de :AdaptadorOF Se descarta una librería genérica porque el punto 4 de sensibilidad exige comparar dos políticas de apertura (conteo contra tasa sobre ventana deslizante) e instrumentar las transiciones de estado. Una librería obligaría a adaptar la instrumentación a su modelo interno y añadiría una variable ajena al estudio.
Inyección de fallas Toxiproxy Es el estándar de facto para inyectar latencia y cortes a nivel de conexión TCP de forma reproducible y modificable en caliente por API. Inyectar la latencia dentro del doble del proveedor sería más simple, pero simularía un servidor lento y no una red degradada, que es el modo de falla que EC-LAT-09 describe.
Doble del proveedor Servicio FastAPI propio Se prefiere sobre una herramienta de mocking general porque debe devolver la forma real del contrato de Open Finance para que el costo de deserialización en :AdaptadorOF sea representativo.
Plataforma de despliegue Docker + Docker Compose V2 Permite fijar límites explícitos de CPU y memoria por componente, condición indispensable para que las corridas sean reproducibles y comparables entre brazos. Se reutiliza el archivo del experimento HA-08.
Almacenamiento Redis 7 (:CacheOF), PostgreSQL 16 (reglas de tarifa) Redis corresponde a ElastiCache Redis de la vista de despliegue. PostgreSQL solo sirve el conjunto de reglas al arranque y no participa del camino crítico, para que la variable bajo estudio sea únicamente la resolución del perfil.
Herramientas de análisis k6, Prometheus, Grafana k6 ofrece el ejecutor de tasa de llegada, imprescindible para medir latencia correctamente, y umbrales declarativos que codifican el criterio de aceptación en el propio script. Grafana permite superponer el estado del interruptor sobre la curva de latencia, que es la visualización que hace evidente el hallazgo de HD-01.3.
Librerías httpx, redis-py (asyncio), asyncpg, orjson, pydantic, prometheus-client Drivers asíncronos en toda la ruta: un driver síncrono dentro de una corrutina bloquea el event loop y produciría una refutación falsa. orjson minimiza el costo de serialización para que no contamine la comparación entre brazos.

8. Distribución de actividades por integrante

Integrante Tareas a realizar Esfuerzo estimado
Alex Mauricio Rodriguez Sanchez Desarrollar la API de Cotización:
• Crear la aplicación FastAPI y el ciclo de vida de los clientes y pools.
• Implementar los cuatro brazos sobre el mismo binario.
• Implementar el presupuesto de abandono a 120 ms y la tarea de refresco en segundo plano.
• Instrumentar el origen y la edad del dato en cada respuesta.
10 horas
Martin Ricardo Romero Ortiz Preparar el entorno de ejecución:
• Extender el docker-compose.yml de HA-08 con Toxiproxy y el doble del proveedor.
• Configurar los cuatro estados del proveedor y el script que los conmuta en caliente.
• Configurar los tableros de Grafana con el estado del interruptor superpuesto a la latencia.
• Apoyar la ejecución de las corridas.
10 horas
John Edwin Guerrero Ayala Desarrollar el Adaptador y el Motor de Tarifa:
• Implementar :AdaptadorOF con timeout duro, pool dedicado y las dos políticas de interruptor.
• Instrumentar transiciones de estado, conexiones en vuelo y peticiones sacrificadas.
• Implementar el motor de tarifa con costo calibrado y tolerancia a perfiles incompletos.
• Implementar la coalescencia por clave del brazo C'.
10 horas
Juan Camilo Acevedo Ospina Planificar y dirigir el experimento:
• Definir el contrato del perfil canónico y la política de expiración por fuente.
• Construir el conjunto de claves que produce cada tasa de acierto objetivo.
• Construir el script de carga y el protocolo de corridas contrabalanceadas.
• Consolidar el presupuesto del Anexo G y redactar el informe final.
10 horas

Total: 40 horas — 1 semana

El esfuerzo asume que el montaje de contenedores y el stack de observabilidad de HA-08 están operativos y se reutilizan. Si el experimento se ejecuta de forma independiente, deben sumarse unas 12 horas de preparación de entorno.


Anexo A — Modelo de fallas del proveedor y diseño experimental

Modelo de fallas del proveedor externo

El punto de sensibilidad 2 exige recorrer cinco estados del proveedor de Open Finance, más su transición de recuperación. Cada estado se implementa como una combinación de configuración del doble del proveedor (latencia de aplicación) y del inyector de fallas (comportamiento de la conexión TCP):

Estado Latencia de aplicación (doble) Comportamiento de conexión (Toxiproxy) Qué representa
Sano Log-normal, mediana 80 ms, cola hasta 200 ms Sin alteración Operación normal declarada por EC-LAT-01/EC-LAT-02
Lento Log-normal, mediana 400 ms, cola hasta 900 ms Sin alteración Proveedor respondiendo pero por encima del presupuesto de 120 ms
Degradado Log-normal, mediana 800 ms, cola hasta 2 s +150 ms de latencia de red inyectada Combinación de aplicación lenta y red congestionada — el escenario que describe EC-LAT-09
Sin respuesta N/A (la petición nunca llega a resolverse) timeout: acepta la conexión TCP y no envía datos El caso más hostil: el pool del adaptador retiene el socket hasta su propio timeout duro de 700 ms
Caído N/A reset_peer: rechaza la conexión inmediatamente Fallo rápido, el circuit breaker debe abrir con el menor costo posible
Recuperación Vuelve a Sano tras una ventana configurable (30 s por defecto) Se retira la alteración de Toxiproxy Verifica HD-01.8: el cierre del interruptor y el retorno del hit-rate de datos frescos

Transición entre estados dentro de una misma corrida. El inyector se reconfigura por su API de administración sin reiniciar los contenedores, de modo que una corrida puede recorrer Sano → Degradado → Sin respuesta → Recuperación sin perder el estado de la caché ni reiniciar el circuit breaker — condición necesaria para que HD-01.8 sea observable.

Variables

Tipo Variable Valores / control
Independiente Estrategia de resolución del perfil A (bloqueante sin caché) / B (cache-aside bloqueante en fallo) / C (actualización oportunista) / C' (C + coalescencia)
Independiente Estado del proveedor Sano / Lento / Degradado / Sin respuesta / Caído / Recuperación
Independiente Tasa de acierto de caché objetivo 99 % / 96 % / 90 % / 50 %
Independiente Política del circuit breaker Por conteo (N fallos consecutivos) / por tasa sobre ventana deslizante
Independiente Tasa de llegada 10 sol/s (tráfico bajo) / 200 sol/s (tráfico alto)
Dependiente Latencia extremo a extremo p50, p95, p99 medidos en el generador de carga
Dependiente Latencia interna del servicio Histograma expuesto por la API
Dependiente Tasa de error Porcentaje de respuestas no exitosas
Dependiente Proporción resuelta con valor de respaldo Porcentaje de respuestas marcadas como "último valor conocido" o "valor por defecto"
Dependiente Peticiones sacrificadas hasta apertura del interruptor Conteo absoluto y como porcentaje de la ventana
Dependiente Invocaciones al proveedor por fallo de caché Solo brazos C y C', para medir el efecto de la coalescencia
Controlada Costo de cómputo del motor de tarifa Fijo y calibrado (~60 ms), idéntico entre brazos
Controlada Tamaño del pool de conexiones del adaptador Fijo e idéntico entre brazos
Controlada Timeout duro del adaptador 700 ms, idéntico entre brazos (EC-LAT-08)
Controlada Presupuesto por dependencia 120 ms, aplica solo en brazos C y C' (EC-LAT-07)
Controlada Representación de la respuesta Contrato de respuesta idéntico entre los cuatro brazos
Controlada Semilla del muestreo de latencia del doble Fija, para que las corridas sean comparables

Control crítico. Al igual que en HA-08, si los cuatro brazos no devuelven exactamente el mismo contrato de respuesta, parte de la diferencia medida provendría del tamaño del payload y no de la estrategia de resolución del perfil. El protocolo incluye una verificación automática de equivalencia antes de cada corrida.

Diseño de las corridas

Tres corridas independientes por brazo, con el orden contrabalanceado mediante un cuadrado latino, igual que en HA-08 y por la misma razón (neutralizar el sesgo del caché de páginas del sistema operativo y del calentamiento de conexiones):

Corrida Orden de ejecución
R1 A → B → C
R2 B → C → A
R3 C → A → B

Cada corrida recorre los seis estados del modelo de fallas en secuencia (Sano → Lento → Degradado → Sin respuesta → Caído → Recuperación), midiendo el escalón de operación regular en cada uno antes de avanzar al siguiente. El brazo C' se corre por separado, una vez confirmado el comportamiento de C, para aislar el efecto de la coalescencia (punto de sensibilidad 5).


Anexo B — Criterios de aceptación

Se acepta la hipótesis HD-01 si, en el escalón de operación regular y en las tres corridas:

  • El p95 del brazo C medido en el servicio es ≤ 225 ms y el p99 ≤ 475 ms, tanto con el proveedor sano como con el proveedor degradado o sin respuesta.
  • Las peticiones sacrificadas hasta la apertura del interruptor son < 1 % de la ventana con tráfico alto (HD-01.5).
  • El hit-rate mínimo que sostiene el umbral queda cuantificado (HD-01.4), aunque no alcance el 96 % propuesto — el resultado en sí es la evidencia buscada.
  • Ninguna corrida queda invalidada por las verificaciones de sanidad definidas en la guía técnica.

Se refuta la hipótesis HD-01 si:

  • El brazo C no alcanza el umbral con el proveedor degradado o sin respuesta, o
  • El brazo C alcanza el umbral solo degradando la proporción de valor de respaldo a un nivel que actuaría considere inaceptable para la calidad de la tarifa, lo cual contradice el propósito declarado de HA-01, o
  • La recuperación del proveedor (HD-01.8) produce una estampida de invocaciones que satura el pool del adaptador.

Resultado intermedio relevante. Si el brazo B ya cumple el umbral con el proveedor degradado (es decir, si la tasa de acierto de caché es suficientemente alta para que el camino bloqueante en fallo casi nunca se ejercite), la actualización oportunista del brazo C constituye complejidad no justificada y la recomendación arquitectónica debe ser la alternativa más simple que satisface el ASR — igual que el criterio ya aplicado en HA-08 para el brazo B frente al C.


Anexo C — Plantilla de registro de resultados

Resultados por brazo y estado del proveedor (escalón de operación regular, tráfico alto)

Brazo Corrida Estado proveedor p50 (ms) p95 (ms) p99 (ms) Error (%) % con respaldo ¿Cumple?
A R1 Sano n/a
A R1 Degradado n/a
B R1 Sano
B R1 Degradado
C R1 Sano
C R1 Degradado
C R1 Sin respuesta
C R1 Caído
C' R1 Degradado

(Repetir el bloque completo para R2 y R3.)

Consolidado y variabilidad

Brazo Estado p95 medio (ms) Desviación estándar ¿Cumple los 3? Veredicto
A Sano
A Degradado
B Sano
B Degradado
C Sano
C Degradado
C Sin respuesta
C' Degradado

Reportar la desviación estándar entre corridas es obligatorio, por la misma razón que en HA-08: un p95 medio dentro del umbral con desviación amplia es evidencia de inestabilidad, no de cumplimiento.

Sensibilidad a la tasa de acierto de caché (punto de sensibilidad 3)

Hit-rate objetivo p95 brazo B (ms) p95 brazo C (ms) ¿Brazo B ya cumple?
99 %
96 %
90 %
50 %

Sensibilidad a la política del interruptor (punto de sensibilidad 4)

Tráfico Política % peticiones sacrificadas ¿< 1 %?
Alto (200 sol/s) Por conteo
Alto (200 sol/s) Por tasa
Bajo (10 sol/s) Por conteo
Bajo (10 sol/s) Por tasa

Efecto de la coalescencia (punto de sensibilidad 5)

Brazo Invocaciones al proveedor por fallo concurrente Saturación del pool observada
C (sin coalescencia)
C' (con coalescencia)

Anexo D — Amenazas a la validez

Derivadas del montaje local

Los umbrales absolutos (225 ms / 475 ms en servicio) no son transferibles. El hardware de desarrollo no es producción ni incluye el salto del :ApiGateway. Se reporta la mejora relativa entre brazos como resultado principal y el valor absoluto como indicativo.

Todo se ejecuta en un solo host. Subestima la latencia real entre :MsCotización, :CacheOF y :AdaptadorOF, que en producción residen en nodos distintos.

Contención de recursos. El generador de carga, Toxiproxy, el doble del proveedor y la plataforma de observabilidad compiten por la misma CPU. Mitigado con límites explícitos por componente.

Caché de páginas del sistema operativo no controlable. Mitigado mediante el contrabalanceo del orden de brazos (Anexo A).

Derivadas del runtime

Variabilidad en la cola de la distribución. Afecta sobre todo al p99. Mitigado con tres corridas independientes y reporte de la desviación estándar.

El muestreo de latencia del doble del proveedor es una aproximación. La distribución log-normal es una elección razonada de forma de cola, no una medición del proveedor real de Open Finance (que aún no existe como integración productiva).

Derivadas del diseño del experimento

El valor de respaldo se modela como constante por ramo. En producción, el valor por defecto podría requerir calibración actuarial más fina que no es objeto de este experimento.

Un solo perfil de carga. Se miden tráfico alto (200 sol/s) y bajo (10 sol/s) como dos puntos discretos, no una curva continua; el punto de quiebre exacto entre ambos regímenes queda para una iteración posterior.

Toxiproxy inyecta la falla en la conexión, no en la aplicación del proveedor real. Es una aproximación deliberada (Sec. 7, tabla de tecnología), pero implica que comportamientos específicos del proveedor real de Open Finance (p. ej. rate limiting con código 429) no están cubiertos por este montaje.


Anexo E — Siguientes iteraciones si se refuta la hipótesis

En orden de menor a mayor costo arquitectónico:

  1. Precarga proactiva de la caché para los clientes con mayor probabilidad de cotizar (por ejemplo, tras el primer contacto en el canal del socio), reduciendo la dependencia del camino frío.
  2. Ajustar el presupuesto por dependencia (hoy 120 ms) si la telemetría muestra que el proveedor sano rara vez lo agota, ganando margen sin tocar el diseño.
  3. Separar el valor de respaldo por segmento de riesgo, en vez de un único valor por ramo, si actuaría determina que la pérdida de precisión no es aceptable de forma uniforme.
  4. Réplicas de :CacheOF con lectura local por zona, si la latencia de red hacia Redis resulta ser una fracción no despreciable del presupuesto.
  5. Revisión del contrato con el proveedor de Open Finance (SLA de latencia, rate limits) si el experimento muestra que ninguna táctica interna alcanza el umbral con el proveedor consistentemente degradado. Esto excede el control arquitectónico del equipo y debe negociarse con el área comercial.

Anexo F — Trazabilidad

Artefacto Identificador
Historia de arquitectura HA-01
Escenarios de calidad EC-LAT-01, EC-LAT-02, EC-LAT-09
Atributo de calidad Latencia
Prioridad (A,A) — ASR
Hipótesis de diseño HD-01 (sub-hipótesis HD-01.1 a HD-01.8)
Tácticas Múltiples copias de datos; incrementar la latencia de los recursos; limitar la respuesta a los eventos; detección de fallas (temporizador); degradación elegante; aislamiento de recursos (bulkhead)
Estilos Llamada-retorno sincrónico, capas + adaptadores, microservicios
Vistas de arquitectura Funcional (componentes), Información (datos), Despliegue (contenedores)
Reutiliza montaje de HA-08 (Docker Compose, stack de observabilidad, protocolo de corridas contrabalanceadas)
Proyecto Jira SOLV
Documento técnico complementario Guia_Tecnica_HA-01.md
⚠️ **GitHub.com Fallback** ⚠️