Event Sink Pattern 
Tags: kafka, events, architecture, pattern
Published: 2020-09-07 15:20:21

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](https://microservices.io/patterns/data/saga.html) y [Outbox Pattern](https://microservices.io/patterns/data/transactional-outbox.html). 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)](https://dev-to-uploads.s3.amazonaws.com/i/cutwnfjfwhw8lf8d4jb2.png)
 
## 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
* [Event Sourcing](https://microservices.io/patterns/data/event-sourcing.html)