Uma operação é idempotente quando executá-la duas vezes deixa o mundo como ficou depois de executá-la uma. Apagar um arquivo é idempotente. Mandar uma mensagem não é, e é nessa assimetria que mora a maioria dos bugs de mensagem duplicada.
Onde ela faz falta de verdade
- Em handlers de webhook, porque a entrega é pelo menos uma vez e uma repetição é normal.
- Em qualquer coisa que você repita depois de um tempo esgotado, porque um tempo esgotado não diz se a escrita chegou.
- Em qualquer coisa que uma fila possa reentregar, o que é toda fila.
Como conseguir, barato
Mantenha uma tabela com os ids sobre os quais você já agiu e insira nela com uma restrição de unicidade antes de fazer o trabalho. Se a inserção falhar, alguém já cuidou deste. Essa é a técnica inteira; não precisa de biblioteca e sobrevive ao reinício no meio do caminho que uma versão em memória não sobrevive.
Insira antes, não depois. Inserir depois deixa uma janela entre fazer a coisa e registrar que você fez, e uma queda nessa janela é exatamente o caso que a tabela deveria cobrir.
O que usar como id
O que o remetente chamar de evento, se ele der um nome. Se não der, monte uma chave com os campos que fazem o evento ser aquele evento — a conta, a conversa e a mensagem, por exemplo — e tire um hash. Uma chave derivada de um carimbo de tempo não é uma chave: a repetição tem outra.
Idempotência não é deduplicar na interface. Quando um duplicado chega a uma tela, você já mandou a segunda mensagem. A verificação fica no topo do handler, antes de qualquer coisa sair.
Perguntas frequentes
Os agentes de IA tornam duplicatas mais prováveis?
Podem. Um agente de IA a quem se pede duas vezes pode enviar duas vezes, e um que tenta de novo depois de um timeout pode não saber que a primeira tentativa funcionou. Dê a ele uma regra nas instruções — leia a conversa de volta antes de enviar de novo — e mantenha uma pessoa aprovando os envios.
O botão Aplicar em uma sala de projeto é idempotente?
Uma proposta em uma sala roda uma única vez. Clicar em Aplicar nela uma segunda vez não muda nada.