Camada Zero · 36 · Idempotência & Exactly-once

A resposta se perdeu na rede. O cliente não sabe se a cobrança passou, então retenta. Sem idempotência, isso vira cobrança dupla. Liga a idempotency key e veja o servidor deduplicar. O capstone da confiabilidade.
Cliente
Servidor
cobradoR$ 0
0Requests enviadas
0Processadas
0Duplicatas barradas
R$ 0Valor cobrado
Mande uma cobrança. Com "derrubar a 1ª resposta" ligado, o cliente vai retentar. Compare com a idempotency key ligada e desligada.
request resposta OK resposta perdida
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ê temVocê adicionaVocê obtém
Entrega at-least-onceProcessamento idempotenteEfeito 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)
}

🧠 Desafio — Idempotência

Roda a cobrança com e sem a key (com "derrubar a 1ª resposta" ligado) antes de responder. As duas últimas são de reflexão: escreve a sua e só então revela o modelo.

🔧 Prática — ache o bug

Esse handler de cobrança cobra o cliente duas vezes às vezes. Clica na linha do bug.