DEV Community

loading...
Cover image for Event Sink Pattern

Event Sink Pattern

cedillomarcos profile image (µ)Marcos ・3 min read

Normalmente un servicio de comandos termina actualizando la base de datos y solemos necesitar que esta actualización sea atómica para evitar inconsistencia en los datos o bugs.

Cuando trabajamos en modelos distribuidos solemos aplicar un Fire&Forget, pero a veces este modelo no es aplicable si tenemos dominios complejos o necesitamos propagar los eventos en un modelo "Domain Event" entre los diferentes dominios para completar un "ciclo completo de trasaccionalidad".

Hay algunos patrones en los que nos podemos apoyar para solucionar esta problemática y que son: SAGA y Outbox Pattern. Aunque ambos tienen sus pros y contras, ambos tienen un problema cuando nuestro sistema procesa Zillions de mensajes de un Topic de Kafka. Y es por ejemplo en el de OutBox Pattern, donde podemos sufrir un backpressure en el sistema

Si ademas le añadimos donde el 2PC noes una opción, debemos buscar patrones alternativos, en este caso llamado "Event Sink".

SinkEventPattern (1)

Descripción

Un mensaje es enviado por una petición de creación desde un servicio externo o llamada REST.
Este mensaje pasará por un servicio de validación que deberá asegurar que los datos del mensaje puede ser almacenado en la bbdd, debe validar tanto el contenido como la capacidad de persistencia. Para conseguir el resultado, es posible que deba apoyarse en patrones CQRS (sobre todo en la parte del query) para verificar el contenido. En caso de no cumplir con la validación puede ir a una DLT para un tratamiento posterior.

Todos los mensajes validados quedan en un Topic para ser procesados, por un lado por una capa separada que inserta estos mensajes en la base de datos sin mayor requerimiento que la propia actualización, siendo un proceso muy ligero, bajo coste y baja latencia. Por otro lado, los mensajes quedan dispuestos para cualquier otro consumidor que necesite los datos para continuar con el proceso de negocio.
De esta manera, aunque la bbdd tenga n milliones de mensajes que procesar y persistir, el flujo de eventos puede continuar por el sistema.

Pros y contras

 Pros

  • Admite Zillions de mensajes
  • Baja latencia
  • Evita el backpressure
  • No interrumpe el proceso de negocio
  • Las transacciones con la base de datos son atómicas

Contras

  • Requiere de una mayor control de errores
  • Es necesario una infraestructura compleja
  • El sistema puede quedar eventualmente inconsistente, con lo que es necesario tener algún mecanismo de compensación
  • Al tener varios topics con la misma información, tendremos volúmenes duplicados de información.

 Modelos de persistencia genérico

Otro punto interesante de este patrón es el referido al propio Sink Service, al implementar este modelo, es posible diseñar un sistema capaz de procesar en base datos cualquier entidad del modelo de dominio sin necesidad de realizar capas adicionales de diseño de DPO's. Esto se debe a que la capa de SSINK cumple con la parte operaciones de SRP básicos de entidades, dejando al lado del Query Segregation (CQRS) la especialización funcional requerida por el dominio funcional del negocio.
Al implementar un modelo genérico en el sistema, solo tendremos que preocuparnos de montar un diseño de validación y consultas específico por dominio.
Este sistema de SINK Genérico es "escalable" para todo el sistema.

Patrones relacionados

Discussion (2)

pic
Editor guide
Collapse
earroyoron profile image
Ernesto λrroyo

Marcos,... ¿esto no es como un CQRS, quizás un patrón un poco especializado de ese modelo? quiero decir, una vez el mensaje (comando) llega al sistema y se valida se convierte en evento (como digo yo a veces "eso ya va a misa") y se publica de forma que se pueden actualizar las vistas de lectura que lo necesiten y, aparte, el modelo que es donde entra el "Event Sink".
Es verdad que todos estos patrones y modelos siempre tienen cosas en común o parecidas, claro,....

Collapse
cedillomarcos profile image
(µ)Marcos Author

Muy buen punto de vista.
Para mi CQRS es un patrón de segregación, que puede venir implementado antes o como parte de este patrón. En este caso....el objetivo es que la parte del Command no venga delimitado por el evento y que la transacción contra la bbdd no afecte al resto del flujo de negocio partiendo en dos elementos diferentes.
Por norma se suele utilizar como fuente de "verdad" o datos consolidados una BBDD, pero en este caso, nuestros datos consolidados ya es un topic de kafka.