⌬ CERBERUS / THE WORKSHOP
CERBERUS_03 / LABORATÓRIO 003 / PARTE 1 + 2

Entre o envio e a confirmação.

Uma reserva foi criada. Um evento seguiu para outro componente. A confirmação se perdeu. O que acontece quando tentamos novamente? Explore os estados do experimento e reproduza cada falha localmente.

Este é um painel explicativo, não um dashboard conectado ao seu computador. Os cenários descrevem testes locais reproduzíveis. Nenhuma mensagem é enviada pelo navegador e nenhum dado pessoal é coletado.

01 / As duas fronteiras

PRODUTORSQLite A: reservas + outbox na mesma transação
HTTP LOCALPOST /events, 127.0.0.1, confirmação e possível retry
CONSUMIDORSQLite B: notificação única por event_id

Em contraste com uma chamada síncrona no mesmo processo, aqui há duas bases, um limite HTTP e dois commits independentes. Por isso, um retorno HTTP pode se perder depois que o consumidor já gravou o efeito.

02 / A falha passo a passo

Abra os estados abaixo para acompanhar o teste de recuperação. O exemplo representa a execução automatizada do repositório, não uma simulação ao vivo no site.

S0 / COMMIT Reserva e outbox persistidos

O produtor escreve reserva e evento pendente dentro de uma transação SQLite. Falhar entre os dois INSERTs provoca rollback e não deixa uma reserva órfã.

S1 / ENTREGA POST para o consumidor

O despachante envia o evento para HTTP de loopback. O consumidor usa outra base SQLite e uma chave única para reconhecer a identidade da mensagem e realizar a deduplicação.

S2 / FALHA O efeito foi gravado, mas o ack não

O consumidor confirma seu commit. Antes de registrar o reconhecimento localmente, o despachante simula uma queda. O evento continua pendente na outbox.

S3 / REINÍCIO Reabrir os dois bancos

Novas instâncias dos repositórios SQLite leem os estados persistidos. O produtor vê uma mensagem ainda não confirmada; o consumidor já possui a notificação.

S4 / RETRY Segunda entrega, um efeito

O produtor reenvia. O consumidor encontra o event_id existente e responde como duplicata sem inserir outra notificação. Só então o produtor confirma sua outbox.

03 / Contratos observáveis

CenárioEstado após falhaResultado esperado no teste
Falha dentro da transaçãoSem reserva, sem eventoRollback atômico
Falha antes do POSTEvento pendenteEntrega posterior possível
Commit remoto antes da confirmação localEvento pendente, efeito remoto gravadoRetry com consumidor idempotente
Payload contraditório para mesmo IDEvento não confirmadoHTTP 409, sem sobrescrever efeito

04 / Reproduzir a bancada

Python 3.11+ e Node 20+, sem serviços externos nem dependências de runtime.

python -m unittest discover -s \
  Cerberus/experiments/03-delivery-boundaries/sqlite_http \
  -p 'test_*.py' -v

cd Cerberus && npm test
Limites: HTTP exclusivamente local, despacho sequencial, sem broker, scheduler, autenticação ou segurança de rede pública. Idempotência de efeito neste cenário não equivale a entrega exactly-once universal. Métricas de latência e throughput ainda não foram coletadas.