Skip to main content

Pesquisa — Padrão de deduplicação e ordering em fila FIFO (análogo AllLogs)

Data: 2026-06-11
Contexto: Task #196020 — Criar fila SQS FIFO para CartRecommendationsHistory
Objetivo: Definir estratégia de deduplicação e ordering da fila AWS_SQS_CART_RECOMMENDATION_HISTORY_FIFO, análoga ao LogQueueConsumerService.


Fonte analisada

Projeto: coezzion-submodule-message-bus/src/Coezzion.MessageBus/MessageBusService.cs
Consumidor de referência: coezzion-service-checkout/src/Checkout.API/Background/LogQueueConsumerService.cs


Como SendFifoAsync publica mensagens

// MessageBusService.cs — SendFifoAsync (linhas 60-83)
public async Task<bool> SendFifoAsync<T>(string queueUrl, T message) where T : Event
{
sendRequest.MessageGroupId = Guid.NewGuid().ToString(); // UUID aleatório
sendRequest.MessageDeduplicationId = null; // não setado
...
}

Comportamento observado:

  • MessageGroupId: Guid.NewGuid() — cada mensagem em um grupo diferente, sem ordering entre mensagens do mesmo RecommendationsId
  • MessageDeduplicationId: não setado — sem deduplicação no nível SQS
  • ContentBasedDeduplication: não habilitado na estrutura da fila

Como o LogQueueConsumerService consome e persiste

// LogQueueConsumerService.cs — linhas 43-86
private async Task RegisterConsumer(...)
{
var messageLogs = response.Messages
.Select(m => JsonSerializer.Deserialize<LogQueueMessageEvent>(m.Body))
.ToList();

// Agrupa por schema (multi-tenant), processa, deleta em batch
await messageBusService.DeleteBatchAsync(queueUrl, response.Messages.Select(x => x.ReceiptHandle));
}

Persistência usa x.Timestamp do evento, não DateTime.Now:

// LogQueueConsumerService.cs — linha 104
PaymentsEcommHistoryModel.CreatePaymentsEcommHistory(..., x.Timestamp)

// linha 132/147
PaymentsHistoryAllLogsModel.CreatePaymentsHistoryAllLogs(..., x.Timestamp, ...)

O Timestamp é populado pelo construtor da classe base Event:

// Event.cs
protected Event()
{
Timestamp = DateTime.Now.ToBrazillianTime();
IdEvent = Guid.NewGuid();
}

Ou seja: o timestamp do registro é o momento da publicação pelo producer, não o momento da persistência pelo consumer. A fidelidade temporal é garantida independente da ordem de chegada.


Implicações para CartRecommendationsHistory

Ordenação (MessageGroupId)

A tabela CartRecommendationsHistory é append-only — cada evento é uma linha independente, sem FK entre eventos. O timestamp de cada evento é gravado no momento do publish (via Event.Timestamp), portanto:

  • Não há risco de corrupção temporal com MessageGroupId = Guid.NewGuid()
  • Não há dependência entre linhas que exija processamento sequencial
  • Query de leitura do histórico usa ORDER BY DateCreated (campo Timestamp), que reflete a ordem real dos eventos

Conclusão: MessageGroupId = RecommendationsId não é necessário para integridade dos dados. Manter o comportamento padrão do submodule (Guid.NewGuid()) é suficiente.

Deduplicação

O LogQueueConsumerService não utiliza deduplicação na camada de infraestrutura:

  • MessageDeduplicationId não é setado por SendFifoAsync
  • ContentBasedDeduplication não está habilitado na estrutura da fila
  • A proteção contra duplicatas é feita na camada de aplicação (INSERT idempotente / constraint UNIQUE)

Conclusão: seguir o mesmo padrão do AllLogs — sem deduplicação explícita no SQS, proteção na camada de aplicação do consumer (task #196021).


Sumário das decisões

AspectoDecisãoJustificativa
MessageGroupIdGuid.NewGuid() (padrão do submodule)Timestamp do evento garante fidelidade temporal; tabela append-only não exige ordering
MessageDeduplicationIdNão setar (padrão do submodule)Mesmo padrão do AllLogs; proteção de duplicatas na camada de aplicação
ContentBasedDeduplicationfalseMesmo padrão do AllLogs
DLQFora de escopoTask futura

Referências

  • coezzion-submodule-message-bus/src/Coezzion.MessageBus/MessageBusService.cs
  • coezzion-service-checkout/src/Checkout.API/Background/LogQueueConsumerService.cs
  • coezzion-submodule-message-bus/src/Coezzion.MessageBus/Events/Event.cs
  • 04-upsell/context/ADR-001-log-queue-service-em-query-handler.md
  • 04-upsell/context/pesquisa-log-queue-service-checkout.md