Kaua3045 / ecommerce

Ecommerce project, to manage products, nfe, orders, using clean architecture and DDD
3 stars 0 forks source link

Precisamos adicionar uma forma de validar qual consumer já processou o evento #101

Closed Kaua3045 closed 6 months ago

Kaua3045 commented 6 months ago

Hoje se dois consumers diferentes processar o mesmo evento vai dar um erro, o certo seria termos um events_metadata e events_consumers assim poderíamos dizer qual é o consumer que esta processando o evento, se fosse em um sistema distribuído provavelmente isso não precisaria ser feito já que teríamos um events_metadata pra cada micro serviço assim não teríamos problema ao salvar o event_metadata. A tabela events_consumers ficaria mais ou menos assim:

CREATE TABLE events_consumers (
   id RANDOM UNIQUE,
   event_id REFERENCE events_metadata (id),
   consumer_identifier String (ENUM)
);

Pra verificar se o consumer X já processou seria algo assim:

SELECT ec.* FROM events_consumers JOIN events_metadata em ON ec.event_id = em.id
WHERE em.id = 'event_id' AND ec.consumer_identifier = 'consumer_identifier';

Pra verificar se aquele consumer já processou um evento mais novo pra quele payload identifier:

SELECT COUNT(*) > 0 
FROM events_metadata em
INNER JOIN event_consumers ec ON em.id = ec.id
WHERE em.payload_identifier = 'SEU_PAYLOAD_IDENTIFIER' 
AND em.version > SEU_VERSION
AND ec.consumer_identifier = 'CONSUMER_DESEJADO';

Na hora de cachear o event_metadata pro exists by Id, podemos fazer algo assim:

final var aKey = EVENT_METADATA_PREFIX + "eventId:" + eventId + ":consumer-identifier:" + consumerIdentifier;
        final var aExistsInCache = this.redisTemplate.opsForValue().get(aKey);

        if (aExistsInCache != null) {
            return true;
        }

Ou então salvar os consumers que já processaram dentro dessa key e dai não precisamos passar o consumerIdentifier na key, isso precisa ser analisado com calma.

Lembrando só precisamos disso por que estamos em um monolito.

Kaua3045 commented 6 months ago

Podemos também adicionar só o consumer_identifier no events_metadata e fazer com que a primary key seja id + consumer_identifier