DEV Community

Alex Carter
Alex Carter

Posted on

Kubernetes: presupuestos de tiempo para correo en CI

Un pipeline de CI puede tardar varios minutos y aun así terminar con un mensaje poco útil: “no llegó el correo”. En una prueba que usa un disposable email address, ese fallo no dice si la aplicación no publicó el evento, si el worker quedó pendiente, si Kubernetes reinició el pod o si el inbox todavía no había recibido el mensaje.

La solución práctica es asignar un presupuesto de tiempo a cada frontera. No se trata de hacer el test más rápido a la fuerza. Se trata de saber qué parte consumió el tiempo disponible para que el siguiente incidente sea menos misterioso.

El síntoma: un timeout que no explica nada

Imagina una prueba de registro en un namespace de staging. El formulario responde 201, pero el test espera el mensaje de confirmación durante 60 segundos y falla. El equipo revisa el log del navegador, ve un “email not found” y vuelve a lanzar el job. A veces pasa; otras no.

Ese retry es tentador, pero mezcla varios relojes:

  • la publicación del evento por la API;
  • la recogida del evento por el worker;
  • el envío al proveedor de correo;
  • la aparición del mensaje en el buzón de prueba;
  • la lectura del mensaje y la confirmación del enlace.

Cuando todos viven bajo un único timeout, la prueba pierde su capacidad de diagnóstico. Un SRE necesita al menos una señal por frontera, aunque sea una señal sencilla.

Define un presupuesto por etapa

Empieza con una tabla que pueda leer cualquier persona del equipo. Por ejemplo, para un flujo normal de 45 segundos:

Etapa Presupuesto Evidencia mínima
API publica el evento 2 s request_id y estado HTTP
Worker recoge el evento 8 s nombre del pod y contador
Proveedor acepta el envío 10 s message_id o error
Mensaje aparece en el inbox 20 s mailbox_id y received_at
Test lee y verifica 5 s estado final y código de salida

Los números no son universales. Son un contrato inicial que luego se ajusta con datos reales. Si la mayoría de las entregas ocurre en cinco segundos, un presupuesto de veinte quizá sea razonable para CI; si la cola tarda más por la noche, hay que medirlo y no adivinarlo.

La prueba debe conservar los tiempos de cada etapa. No guardes el contenido completo del mensaje en un artefacto público: normalmente basta con un identificador, un hash de dirección y los estados. Así el diagnóstico ayuda sin filtrar datos de prueba.

Qué observar en Kubernetes

En Kubernetes, un fallo de correo puede estar oculto detrás de una ejecución aparentemente sana. Revisa cuatro señales antes de aumentar el timeout:

  1. Reinicios del worker. Un restartCount nuevo cerca del momento del envío puede explicar una cola que no avanzó.
  2. Edad del pod. Si el despliegue rotó durante la prueba, el evento quizá quedó en memoria y no llegó a ser confirmado.
  3. Profundidad de la cola. Una cola creciendo con consumidores listos indica presión; una cola quieta con cero consumidores indica otro problema.
  4. Correlación. El mismo request_id debe aparecer en la API, el worker y el adaptador de correo.

Para una consulta rápida, un job de diagnóstico puede producir algo como esto:

run=ci-1842 request=req-7f2 worker=mail-worker-6d8c
api=accepted worker=processed provider=accepted inbox=pending
pod_restarts=0 queue_depth=3 elapsed=18s
Enter fullscreen mode Exit fullscreen mode

Ese estado “inbox=pending” es mucho más útil que un timeout genérico. Si la cola sigue creciendo, el test no debe culpar al buzón todavía.

Una implementación sencilla en CI

Usa un reloj monotónico y registra una línea al entrar y salir de cada etapa. El adaptador del buzón debería aceptar un deadline absoluto, no reiniciar el contador completo en cada poll. De lo contrario, diez intentos de seis segundos pueden convertir un presupuesto de veinte segundos en un minuto sin que sea evidente.

También conviene reservar una dirección por ejecución. Un buzón compartido hace difícil saber si el mensaje actual llegó o si el test leyó un correo viejo. En documentación y búsquedas internas pueden aparecer errores como tempail o tamp mail com; no los uses para diseñar la lógica, pero sí puedes mapearlos a la terminología correcta en el buscador del equipo.

Cuando el mensaje no llega, conserva el resumen de estados y termina con una causa concreta: worker-timeout, provider-rejected, inbox-timeout o verification-timeout. Así un retry puede ser selectivo y no repetir toda la suite sin motivo.

Para sistemas con varios consumidores, merece la pena formalizar el contrato de señales. El artículo sobre contratos de correo para automatizaciones muestra una forma de pensar en eventos y estados sin depender de un log enorme. Y para las alertas operativas, las alertas de failover comprobables siguen la misma idea: una alerta debe poder probarse con una evidencia observable.

Checklist para el siguiente incidente

  • ¿Cada etapa tiene un presupuesto separado?
  • ¿La prueba conserva request_id, mailbox_id y message_id sin guardar datos innecesarios?
  • ¿El worker tuvo reinicios o perdió el lease del evento?
  • ¿La cola avanzaba, estaba bloqueada o no tenía consumidores?
  • ¿El deadline era absoluto o se reiniciaba en cada intento?
  • ¿El resultado final distingue entrega, lectura y verificación?

Un timeout sigue siendo una limitación real, pero deja de ser una explicación vacía. Con presupuestos pequeños, señales correlacionadas y un buzón aislado por ejecución, Kubernetes y CI pueden decirte dónde está el problema antes de que alguien pulse “reintentar”.

Top comments (0)