A rede não distingue "request perdida" de "resposta perdida". O cliente que não recebe resposta só tem uma saída segura: retentar. Logo, todo sistema confiável é at-least-once (pode entregar de novo). A correção não está na entrega, está no processamento: torne a operação idempotente e o retry vira inofensivo.
| Você tem | Você adiciona | Você obtém |
| Entrega at-least-once | Processamento idempotente | Efeito exactly-once |
Exactly-once delivery não existe numa rede não confiável (problema dos dois generais). Exactly-once effect existe, e é isso que você persegue.
Idempotency key no servidor
func cobrar(w http.ResponseWriter, r *http.Request) {
key := r.Header.Get("Idempotency-Key")
// já processei essa key? devolve o resultado original.
if res, ok := store.Get(key); ok {
writeJSON(w, res)
return
}
res := aplicarCobranca(10)
// grava sob unique constraint: duas threads não duplicam (aula 24/09)
store.Put(key, res)
writeJSON(w, res)
}