Seu sistema não falha uma vez. Ele falha várias.

Seu sistema não falha uma vez. Ele falha várias.

Seu sistema não falha uma vez. Ele falha várias.

Japa Tela Preta #6

Existe uma suposição silenciosa que quase todo mundo faz quando está desenvolvendo um sistema: as coisas acontecem uma vez.

Uma requisição chega, um processo executa, o dado é salvo, fim. Linear, previsível, limpo. No papel, tudo faz sentido. Você implementa o fluxo, testa, valida e segue em frente com a sensação de que aquilo está resolvido.

Só que produção não funciona assim.

Teve um caso clássico que deixa isso muito claro. Um fluxo de pagamento aparentemente simples: o sistema recebia a confirmação de um gateway, registrava o pagamento e seguia o processo normal. Tudo certo, funcionando como esperado… até começarem a aparecer pagamentos duplicados.

A primeira reação, de novo, foi procurar bug. Alguma validação faltando, algum controle mal feito, alguma condição que deixou passar. Mas quando fomos investigar mais fundo, a realidade era outra.

O gateway estava reenviando a mesma notificação.

Não por erro. Por segurança.

Ele não tinha certeza de que o sistema tinha recebido corretamente, então fazia o que qualquer sistema resiliente faz: tentava de novo.

E o nosso sistema? Processava de novo.

Sem questionar.

Sem proteção.

Sem saber que aquilo já tinha sido feito.

Resultado: o mesmo pagamento registrado duas vezes, gerando efeitos em cascata no resto do sistema.

E esse tipo de cenário não é exceção. Ele é o padrão.

Uma mensagem pode ser entregue mais de uma vez. Um job pode rodar novamente. Um retry pode acontecer sem você perceber. Uma fila pode reprocessar eventos depois de uma falha. E tudo isso acontece justamente quando o sistema está tentando se manter saudável.

Ou seja, o problema não vem do erro.

Vem da recuperação do erro.

É nesse ponto que muita gente entende, da pior forma, um conceito que parecia desnecessário até então: idempotência.

Idempotência não é teoria bonita. É garantia prática de que uma operação pode acontecer várias vezes sem causar efeitos colaterais indesejados. Você pode executar duas, três ou dez vezes… e o estado final continua o mesmo.

Sem isso, cada retry vira um risco.

Com isso, retry vira uma rede de segurança.

Porque você para de depender da premissa de que “isso só vai acontecer uma vez” e começa a aceitar a realidade: em sistemas distribuídos, repetição é inevitável.

E quando você constrói assumindo isso, o comportamento muda completamente. O sistema deixa de ser frágil a duplicidade, deixa de sofrer com reprocessamento e passa a lidar com falhas de forma muito mais previsível.

No começo, você escreve código pensando no caminho ideal.

Depois, você começa a projetar pensando no que acontece quando o caminho ideal não acontece.

E isso inclui aceitar que operações vão se repetir, mensagens vão duplicar e eventos vão chegar fora de ordem.

Sistemas maduros não são aqueles que evitam falhas.

São aqueles que continuam corretos mesmo quando as coisas acontecem mais de uma vez.

E quando você vira essa chave, você para de tentar construir um sistema “perfeito”…

e começa a construir um sistema que aguenta o mundo real.

Foto de Willian Sanada
Willian Sanada