DEV Community

Cover image for Race condition em sistemas distribuídos
Mayderson Mello
Mayderson Mello

Posted on

Race condition em sistemas distribuídos

Cenário:

Temos um serviço de pagamento que consome dados de duas filas:

clients-processor: fila com dados de clientes para cadastrar
payment-processor: fila com dados de um pagamento para ser processado

Esse serviço processa os pagamentos, porém ele só processa pagamentos de clientes que estão cadastrados.

Problema:

Como tratar o problema de race condition quando um evento de pagamento é recebido primeiro que o evento de cadastro de clientes (sem utilizar bancos de dados). Para simplificar mais temos a premissa que o evento de cadastro de cliente sempre será recebido.

A solução:

clients-processor: Uma fila para evento de cadastro de clientes
payment-processor: Uma fila para evento de pagamentos
payment-reprocessor: Uma fila para reprocessar eventos de pagamentos utilizando o plugin delayed_message_exchange do RabbitMQ

Quando um evento de pagamento é recebido e o cliente ainda não está cadastrado, aumentamos o valor do delay da mensagem em 1 segundo. A mensagem é então encaminhada para a fila de reprocessamento. Em algum momento, quando um cliente for efetivamente cadastrado, o pagamento correspondente será processado.

Para exemplificar melhor, o fluxo grama abaixo mostra a abordagem utilizada:

Race condition

Exemplo:

Crie uma aplicação com Golang + RabbitMQ para implementar toda abordagem comentada acima, você pode encontrá-la no meu GitHub, e lá terá as instruções para rodar.

Para o exemplo, vamos enviar duas mensagens, uma com o pagamento e outra com o novo cliente.

Ao receber um pagamento de um cliente com o ID 1, o pagamento não vai ser processado, a mensagem é enviada para uma fila e o delay vai aumentando, até que a mensagem de cadastro do cliente é recebida, no proximo recebimento do pagamento ele será processado e a operação finaliza.

Vídeo da aplicação:

Bom é isso, espero que tenha gostado da estratégia, sobre a aplicação, a mesma foi escrita em Golang, mas mesmo que você não desenvolva com Go, é uma aplicação muito simples e acredito que não terá problema em entender o código.

Top comments (0)