Idempotencia

Cómo manejar reintentos al enviar mensajes

Idempotencia (Reintentos al enviar mensajes)

Todo mensaje en Shinkansen Core tiene uno o más identificadores (message_id y en ciertos mensajes también shinkansen_message_id) como parte de su cabecera (header). Esto permite que se pueda enviar el mismo mensaje más de una vez sin que eso sea problema.

Esto es últil cuando el emisor de un mensaje no está seguro si el receptor lo procesó exitosamente. Por ejemplo, cuando falla la red justo entre el envío del mensaje y la recepción del status code de respuesta.

En esos casos, el emisor del mensaje puede simplemente reenviar la misma petición. Según lo que haya pasado en el lado receptor, ocurrirá una de las siguientes cosas:

  • El receptor podrá procesar el mensaje si es que no lo había procesado antes (por ejemplo, el fallo de red ocurrió antes de recibir la petición).

  • El receptor descartará el mensaje porque ya había procesado antes un mensaje del mismo emisor con el mismo identificador. La respuesta indicará que el mensaje había sido procesado e incluirá también la respuesta original. En el caso del API Rest, esto se indica mediante el código HTTP 409 (Conflict).

👍

En la práctica:

  • Cuando envíes un mensaje a Shinkansen Core debes asignarle un message_id identificador, único globalmente.
    • Si no tienes seguridad que Shinkansen Core recibió el mensaje (ej: obtuviste una excepción de error de conexión o un error 500 en lugar de una respuesta HTTP 2xx o 4xx), debes reintentar cuantas veces sea necesario usando el mismo message_id.
    • Cuando recibes un código HTTP 409 debes tratar el contenido respuesta de igual manera que un HTTP 2xx. Significa que Shinkansen Core te está avisando que el mensaje ya había sido procesado previamente. Y te está re-enviando la misma respuesta que originalmente no recibiste.
  • Cuando recibes una respuesta en tu webhook, debes asegurarte que el shinkansen_message_id sea único.
    • Si ya habías visto ese mismo shinkansen_message_id antes, entonces debes responder con el código HTTP 409.
  • Cuando has procesado una respuesta en tu webhook, puedes responder con el código HTTP 200 y Shinkansen Core no reintentará más.
    • Es útil no responder hasta que realmente hayas persistido la respuesta. Así en caso de alguna excepción o caída de tu red podrás recibir nuevamente el mensaje desde Shinkansen Core.

Nota que la idempotencia funciona a nivel de mensajes, no de transacciones.

Si envías el mismo id de transacción en un mensaje B que ya había sido incluida en un mensaje A y el mensaje A había sido procesado por Shinkansen, entonces el mensaje B será rechazado completamente con todas las transacciones que incluya. Por eso recomendamos que siempre reintentes con exactamente el mismo mensaje y las mismas transacciones contenidas en el mensaje.

👍

En la práctica:

  • Siempre que re-intentes un mensaje, debes mantener exactamente las mismas transacciones que incluía el mensaje original, con sus mismos transaction_ids.
  • Los transaction_ids deben ser únicos globalmente. No debes reutilizar un transaction_id que ya haya sido enviado en otro mensaje, o fallará el mensaje completo.
  • Cuando obtienes una respuesta de error de una transacción y quieres reintentar (ej: el error era de indisponibilidad de un banco destino), la nueva transferencia debe llevar un transaction_id diferente e ir dentro de un mensaje con un message_id único y nuevo.