Tema representativo de entrevista

Entrevista general: ¿Cómo diseñarías el ciclo de vida de una sesión de WebTransport y un apagado ordenado (graceful shutdown)?

GeneralDifícil
Equipo editorial de Offer.ccPublicado Actualizado

Pregunta

Necesitas WebTransport para colaboración en tiempo real y sincronización de estado de baja latencia. Diseña el establecimiento de la sesión, los ciclos de vida de flujos y datagramas, la reconexión, el apagado ordenado y la limpieza del lado del servidor.

Planteamiento y contexto

Una aplicación de colaboración en tiempo real debe entregar operaciones de documentos de forma confiable, mientras envía posiciones del cursor y latidos (heartbeats) que pueden descartarse. El equipo eligió WebTransport pero no ha definido el comportamiento de cierre, los cambios de red, la reconexión, la contrapresión ni la limpieza. Diseña el ciclo de vida y explica los límites entre los flujos confiables, los datagramas no confiables y una conexión HTTP/3.

La API W3C WebTransport expone flujos confiables y datagramas no confiables; RFC 9297 define los datagramas HTTP. Una respuesta sólida separa la sesión de aplicación del transporte y no trata a close() como prueba de que cada mensaje de negocio fue entregado.

Qué está evaluando el entrevistador

  • Distinguir entre el cierre de sesión, el cierre de flujo, la pérdida de datagramas y el fallo de red.
  • Diseñar la reconexión, la recuperación de sesiones, los números de secuencia, la idempotencia y las instantáneas (snapshots).
  • Manejar la contrapresión de flujos, los límites de datagramas, los clientes lentos y los topes de recursos.
  • Definir códigos de cierre, motivos, tiempos de espera (timeouts) y observabilidad.
  • Establecer límites explícitos para el navegador, el proxy, HTTP/3 y los mecanismos de contingencia (fallback).

Preguntas para clarificar

  1. ¿Qué mensajes deben ser confiables y ordenados, y cuáles pueden descartarse o reducirse al valor más reciente?
  2. ¿Puede una sesión recuperarse tras cambios de red? ¿Qué tiempo de recuperación e historial de operaciones son aceptables?
  3. ¿Qué límites aplican a las sesiones concurrentes, flujos y tasa de datagramas por usuario?
  4. ¿El cierre es iniciado por el usuario, por mantenimiento, por expiración de autenticación, por sobrecarga o por un error de protocolo?
  5. ¿Los navegadores y proxies soportan WebTransport sobre HTTP/3, y cuál es el fallback explícito?

Respuesta en 30 segundos

Separa el ID de sesión de aplicación de una conexión WebTransport individual. Envía operaciones confiables a través de flujos con números de secuencia y claves de idempotencia; envía cursores y heartbeats como datagramas con tolerancia a pérdidas. Ante fallos, retén brevemente el estado de la sesión en el servidor; reconecta con retroceso exponencial (exponential backoff) y la última secuencia confirmada, y luego recupérate a partir de una instantánea más deltas. Para un cierre ordenado, detén nuevo trabajo, drena los flujos confiables, envía un marcador de finalización de aplicación, cierra con un código y aplica un tiempo de espera estricto (hard timeout). Limita cada búfer y recurso.

Respuesta a profundidad

1. Establecer sesiones de aplicación y de transporte

Un ID de sesión de aplicación representa la pertenencia lógica del usuario a una sala de colaboración; una instancia de WebTransport es una única conexión de red. Tras el saludo (handshake), valida origen, autenticación, inquilino (tenant) y permisos de sala, crea un ID de conexión y asígnalo a la sesión de aplicación. La reconexión crea un nuevo ID de conexión y nunca otorga la sesión de otro usuario.

Almacena la última secuencia de operación confirmada, la versión de la instantánea, las suscripciones y la expiración. Tras una desconexión, marca el estado de la aplicación como suspendido durante un TTL corto antes de liberarlo.

2. Elegir flujos o datagramas por mensaje

Las operaciones de documentos, los cambios de permisos y los reconocimientos (acknowledgements) utilizan flujos confiables con entramado explícito, versión, número de secuencia y clave de idempotencia. Los cursores, métricas en vivo y heartbeats utilizan datagramas, y los receptores descartan marcas de tiempo o versiones obsoletas. Nunca coloques un evento de negocio de entrega obligatoria en un datagrama.

Los datagramas no ofrecen garantías de entrega, orden o retransmisión, y tienen límites de tamaño por ruta e implementación. Mide la pérdida y la latencia, reduce la frecuencia o envía únicamente el estado más reciente. Los flujos confiables utilizan la contrapresión de WritableStream en lugar de colas de memoria no acotadas.

3. Manejar la contrapresión y los clientes lentos

Establece una ventana de envío, un límite de reconocimientos pendientes y un tamaño máximo de trama por cada flujo confiable. Cuando una escritura permanezca pendiente, pausa a los productores; al vencer el tiempo de espera, desconecta o reduce las suscripciones no críticas. Utiliza cubos de fichas (token buckets) y presupuestos por sesión para los datagramas; descartar un cursor antiguo es preferible a bloquear las operaciones de documentos.

Limita también la cantidad de sesiones, la cantidad de flujos, la decodificación concurrente y la memoria total. Agrega métricas por inquilino para que un cliente lento no pueda consumir el bucle de eventos (event loop).

4. Diseñar la desconexión y la recuperación

El cliente asigna números de secuencia locales y claves de idempotencia a las operaciones confiables y avanza un punto de control (checkpoint) tras el reconocimiento. El handshake de reconexión incluye el ID de sesión, la última secuencia confirmada y las capacidades. El servidor verifica la propiedad de la sesión y devuelve una instantánea, deltas o un error irrecuperable.

Pausa los nuevos efectos secundarios durante la recuperación para que las conexiones antiguas y nuevas no puedan enviar datos concurrentemente. Utiliza una época (epoch) para invalidar escrituras de la conexión anterior y reabre los productores únicamente después de que se complete la recuperación.

5. Diseñar el apagado ordenado

Durante el mantenimiento, transmite el estado de drenado (draining), rechaza nuevas sesiones y detén los datagramas no críticos. Permite que los flujos confiables terminen su trama actual y envíen un marcador de finalización de aplicación, y luego cierra la sesión tras una espera acotada. El close() del navegador comunica el cierre de la sesión y la información de cierre; no constituye un reconocimiento de negocio.

Clasifica los códigos de cierre para salida normal, expiración de autenticación, sobrecarga, error de protocolo y mantenimiento. Mantén los motivos breves y sin datos confidenciales. Al alcanzar el hard timeout, libera los recursos de inmediato y registra las operaciones no finalizadas.

6. Reverificar autenticación y cambios de red

Cada conexión nueva o recuperada revalida credenciales, origen, inquilino y permisos de sala. No te limites a recuperar con base en el ID de sesión únicamente. Un cambio de red puede alterar la dirección; la recuperación de la aplicación utiliza una nueva conexión, mientras que el epoch impide que la ruta antigua escriba.

Si WebTransport o HTTP/3 no están disponibles, negocia un fallback explícitamente y reitera las diferencias de confiabilidad, latencia y seguridad. No apliques la semántica de cierre de WebSocket a los datagramas.

7. Observar y poner a prueba los modos de falla

Registra la creación de conexiones, fallas de handshake, código y motivo de cierre, contrapresión de flujos, datagramas descartados, cantidad de reconexiones, duración de la recuperación y operaciones no confirmadas. No registres tokens ni contenido sensible de documentos. Segmenta las métricas por cliente, tipo de red e inquilino.

Pon a prueba el mantenimiento, cambios de red móvil, bloqueo de proxies HTTP/3, clientes lentos, ráfagas de datagramas y reconexiones duplicadas. Los criterios de aceptación incluyen la ausencia de efectos secundarios duplicados, límites explícitos de recuperación, limpieza de sesiones expiradas y una latencia de cierre acotada.

Respuesta modelo

Separaría la sesión de aplicación de la conexión WebTransport. Las operaciones confiables de documentos utilizan flujos con números de secuencia y claves de idempotencia; los cursores y heartbeats utilizan datagramas con tolerancia a pérdidas. El cliente almacena un checkpoint y se reconecta con el ID de sesión y la última secuencia confirmada. El servidor verifica el usuario y el inquilino, restaura a partir de la instantánea más los deltas, y utiliza un epoch para invalidar escrituras antiguas.

El apagado ordenado entra en fase de draining, detiene nuevos mensajes y datagramas no críticos, drena los flujos confiables, envía un marcador de finalización de aplicación y luego cierra con un código y un hard timeout. Limita sesiones, flujos, búferes y reconexiones; monitorea la pérdida, la contrapresión, los motivos de cierre y el tiempo de recuperación. Negocia cualquier fallback explícitamente.

Errores comunes

  • Tratar los datagramas como mensajes confiables o close() como un reconocimiento de negocio.
  • Crear una nueva conexión tras un fallo sin checkpoint, epoch o clave de idempotencia.
  • Almacenar en búfer indefinidamente los datos de clientes lentos, agotando la memoria o el event loop.
  • Recuperar mediante el ID de sesión sin revalidar usuario, inquilino, origen y permisos.
  • Omitir el drenado, un hard timeout o la auditoría de operaciones no finalizadas durante el cierre.
  • Ignorar el bloqueo de HTTP/3, el soporte del navegador y el comportamiento de los proxies.
  • Registrar tokens completos, contenido de documentos o motivos de cierre confidenciales.

Preguntas de seguimiento y respuestas

¿Qué debe ir en los datagramas?

Valores efímeros y tolerantes a pérdidas, como cursores, posturas temporales y heartbeats de alta frecuencia. Las operaciones de negocio que deben llegar obligatoriamente utilizan flujos confiables.

¿Cómo evitas operaciones duplicadas tras la reconexión?

Asigna claves de idempotencia y números de secuencia, deduplica por sesión y epoch en el servidor, y avanza el checkpoint solo tras el reconocimiento.

¿Cómo debería funcionar el apagado por mantenimiento?

Detén las nuevas sesiones y transmite el draining, detén datagramas no críticos, drena flujos confiables, envía un marcador de finalización y luego cierra normalmente. Fuerza la limpieza al alcanzar el hard timeout.

¿Qué sucede cuando expira el TTL de la sesión?

Devuelve un error irrecuperable y exige reautenticación y nueva unión a la sala. Un ID de sesión antiguo no debe extender los permisos.

¿Qué pasa si los datagramas son demasiado grandes o la pérdida es alta?

Limita el tamaño y la tasa, comprime o agrupa el estado (coalesce), y conserva únicamente el valor más reciente. Un evento de negocio no puede depender de un datagrama no confiable.

¿Cómo demuestras que un fallback preserva la semántica?

Documenta las diferencias de confiabilidad, ordenamiento, recuperación y autenticación por protocolo. Prueba desconexiones, bloqueo de proxies, clientes lentos y reconexiones duplicadas mientras mides los efectos secundarios duplicados.

Fuentes públicas

Preguntas relacionadas