Saltar a contenido

ADR-0003 · Política de reintentos de jobs de salida: timeout explícito, backoff exponencial y retry_after > timeout

  • Estado: aceptado
  • Decisores: hquintero
  • Fecha de la decisión: 2026-06-16 (commit 3da7da2)

Contexto y problema

Los jobs de salida (WooCommerce, Medusa, TiendaNaranja, Contimarket, UMarket) hacen HTTP a APIs externas y heredaban el timeout de 60s del worker, con reintentos planos de release(60). Cuando una API externa respondía lento, los jobs excedían el timeout (MaxAttemptsExceededException), se reintentaban en bucle cada 60s y ocupaban los workers, atascando todas las colas de salida (incidente de junio 2026). Además retry_after=90 en las conexiones era menor que el trabajo real, lo que producía doble ejecución del mismo job.

Opciones consideradas

  1. Política uniforme: $timeout = 120 explícito por job, $backoff exponencial [60, 300, 900], trait RetriesWithBackoff que respeta Retry-After (429/503), y retry_after = 150 (> timeout) en las conexiones de cola.
  2. Mantener reintentos planos y subir el número de workers.

Decisión

Opción 1, aplicada en los cinco canales de salida (app/Jobs/Concerns/RetriesWithBackoff.php, config/queue.php). Regla derivada: todo job que hace HTTP externo declara $timeout, y el retry_after de su conexión debe ser mayor que ese timeout (si no, la cola re-despacha el job mientras sigue corriendo → doble ejecución).

Consecuencias

Positivas

  • Los fallos persistentes retroceden (1/5/15 min) y dejan pasar a los jobs que sí pueden completar; se respetan los Retry-After de las APIs.
  • Se eliminó la doble ejecución por retry_after < timeout.

Negativas / deuda asumida

  • Un producto con fallo transitorio puede tardar hasta ~21 min en publicarse (suma de la escala de backoff).
  • Tras cambiar config de colas hay que config:clear + horizon:terminate; con config cacheada la política vieja sigue activa (ver runbook, falla 3).