Deadline
Qué es
Un deadline expresa hasta cuándo una operación completa dispone de presupuesto temporal para producir el resultado requerido. Puede representarse como un instante límite o como tiempo restante, según el protocolo. Su propósito es conservar un límite común a través de fases, llamadas dependientes y reintentos.
timeout limita una espera local; deadline limita el presupuesto de la operación que engloba esas esperas. Ambos pueden implementarse con temporizadores, y algunas APIs usan los nombres de forma distinta. Lo importante es saber dónde empieza el presupuesto, qué incluye y si se renueva al iniciar una fase.
gRPC documenta la diferencia entre un instante deadline y una duración timeout, además de su propagación a llamadas dependientes. Es un ejemplo de contrato de transporte, no una dependencia del concepto. gRPC: Deadlines.
Qué problema resuelve
Una solicitud atraviesa autenticación, una cola local, consulta de inventario y composición de respuesta. Si cada parte inicia una espera de un segundo, el caller puede terminar esperando varios segundos aunque solo admita uno para el recorrido completo.
Los reintentos añaden otra fuente de expansión: cada intento puede consumir un timeout nuevo y una espera de backoff. Sin un límite compartido, acotar cada intento no acota la operación total.
El deadline permite dejar de iniciar trabajo que ya no puede producir un resultado útil dentro de ese contrato. No garantiza que todo efecto remoto se detenga exactamente al vencer; limita una intención de espera y necesita cooperación de las capas que la ejecutan.
Presupuesto y propagación
El caller fija un límite adecuado al caso de uso. Cada etapa calcula lo que queda después del tiempo ya consumido y aplica un límite descendente: una dependencia no debería recibir más presupuesto que el disponible en su caller.
Conceptualmente:
remaining = operation limit - elapsed time
attempt allowance <= remaining - response/cleanup reserveLa reserva final evita gastar todo el tiempo en el último intento y no poder ensamblar la respuesta o terminar recursos locales. Es una decisión del contrato, no una constante universal. Si ya no queda presupuesto suficiente, iniciar otra llamada puede añadir carga sin una posibilidad razonable de responder a tiempo.
Google SRE recomienda propagar el límite a través del árbol de llamadas y comprobar el tiempo disponible en las distintas etapas, incluyendo trabajo que quedó esperando en colas. Addressing Cascading Failures: Latency and Deadlines.
Propagar no significa repartir el mismo tiempo inicial a cada hijo. En llamadas secuenciales se descuenta lo ya gastado. En llamadas paralelas, los hijos pueden compartir el mismo límite final, pero eso no aporta un presupuesto ilimitado de CPU, conexiones o carga agregada.
Relojes y representación
Dentro de un proceso, medir duración con un reloj monotónico evita que un ajuste del reloj civil cambie arbitrariamente el tiempo transcurrido. Entre máquinas, copiar un timestamp absoluto sin considerar diferencias de reloj puede dar presupuestos falsos.
Un protocolo puede transmitir tiempo restante y descontar el elapsed time que conoce, como hace gRPC, o definir cómo interpretar timestamps y su incertidumbre. La implementación necesita tener en cuenta tránsito y colas: cada hop no debe reiniciar por defecto el presupuesto original.
No todos los frameworks propagan automáticamente el contexto temporal. Hay que comprobar lo que llega a llamadas salientes, workers y operaciones de almacenamiento. Un header que nadie consulta no limita el trabajo.
Ejemplo
Una solicitud dispone de 900 ms. Cola y validación consumen 120 ms; consultar inventario consume otros 280 ms. Quedan 500 ms para resolver un resultado incierto y preparar la respuesta.
Si se reservan 50 ms para la salida y un nuevo intento necesita hasta 300 ms, una espera propuesta de 200 ms ya no cabe junto a ambas partes. La política debe detenerse o elegir otro camino válido, no recortar silenciosamente la espera y seguir actuando como si el presupuesto fuese nuevo.
| Diseño | Qué ocurre |
|---|---|
| Cada fase recibe 900 ms nuevos | La operación puede exceder ampliamente el límite original. |
| Cada fase recibe presupuesto restante | Las decisiones de espera y reintento consideran el mismo límite final. |
| El caller vence, pero no propaga el contexto | Los servicios descendentes pueden continuar trabajo que ya no servirá a esa respuesta. |
Los números son ilustrativos. No todas las fases consumen sus máximos, pero un diseño no debe depender de que nunca lo hagan.
Expiración, cancelación y efectos
Al vencer, el caller deja de esperar o produce el resultado de expiración previsto. Puede solicitar cancelación y evitar trabajo posterior. Los participantes necesitan observar esa señal y liberar lo que puedan; una transacción ya confirmada no queda deshecha.
Una escritura puede terminar antes del deadline y perder su respuesta. El resultado seguirá siendo desconocido para el caller, aunque su tiempo de espera haya terminado. idempotency o una consulta de estado permiten resolverlo sin asumir ausencia de efectos.
Un deadline de respuesta tampoco es lo mismo que la caducidad de negocio de un pedido o mensaje. Si una tarea durable ya fue aceptada, esa obligación puede continuar después de expirar la solicitud original. El worker necesita un presupuesto de ejecución y una política de validez propios; prolongar la llamada original no es la única forma de recuperar progreso.
Failure scenarios y trade-offs
- Colas largas: recibir una solicitud no demuestra que quede tiempo útil para procesarla.
- Límites reconstruidos en cada hop: pueden multiplicar duración aunque todas las capas tengan timeouts.
- Relojes desalineados: un instante interpretado sin contrato puede expirar demasiado pronto o demasiado tarde.
- Cancelación ignorada: el caller termina, pero los descendientes retienen recursos.
- Presupuesto irrealmente corto: descarta trabajo normal y puede estimular reintentos que agravan el problema.
Usarlo cuando el recorrido necesita una latencia total acotada y las etapas pueden cooperar. No tratarlo como una garantía física de terminar todo el sistema al mismo instante ni como un sustituto de límites de concurrencia. Medir tiempo de cola, presupuesto recibido, motivos de agotamiento y trabajo que continúa después ayuda a verificar su cumplimiento.
retry debe respetar este presupuesto; timeout protege esperas concretas. resilience-patterns conecta ambas preguntas sin confundir el tiempo disponible con la seguridad de repetir un efecto.