Pular para o conteúdo

apps/messaging-streaming/event-carried-state-transfer

071 · Comunicação & Mensageria · ≈ 6 min de estudo

Event-Carried State Transfer

O evento carrega o estado completo do recurso: o receptor monta a própria réplica com o que chega e nunca chama o serviço de origem. Troca payload maior e acoplamento de schema por autonomia — o receptor responde mesmo com a origem fora do ar.

passos
6
arquivos
7
teste
1
tecnologias
4
Infraestrutura realTypeScriptBunRedisDocker
Baixar cartão

Cenário

O serviço de relatórios de um banco digital mostra saldo e status das contas sem depender do serviço de contas. Cada alteração de conta publica o estado inteiro; o serviço de notificação avisa o cliente de cada PIX com os dados do próprio evento. Se relatórios ficar fora do ar, alcança o que perdeu ao voltar; se contas cair, relatórios segue respondendo.

Planta

Sequência
8/8
XADD com.bank.account.updated v1 (estado completo)1XADD com.bank.transaction.processed (transação completa)2XADD com.bank.account.updated v23XREADGROUP4SET NX no id do evento, notifica uma vez, XACKXREADGROUP5Lua: grava só se versão maior6offline enquanto v3 e uma cópia tardia de v2 são publicadasXREADGROUP a partir da posição do grupo7v3 aplicada, v2 descartada8origem fora do ar: a réplica responde sozinhaServiço de contasRedis Stream account:v1:eventsNotificação (grupo notification)Relatórios (grupo report)Réplica report:v1:account:id
8

8 passos — reproduza para seguir o fluxo

Como funciona

6 passos

Evento leva o estado completo.

Esconde cada passo: lembre antes de tocar para revelar.

  1. 01

    O serviço de contas publica CloudEvents (id, source, type no passado, correlationid) com o estado completo em data, via XADD no stream account:v1:events

  2. 02

    Cada receptor lê pelo seu consumer group: todos recebem todos os eventos e cada um trata só o tipo que lhe interessa; tipo desconhecido é ignorado, não derruba o receptor

  3. 03

    Relatórios grava o estado num Hash por conta com script Lua que compara a versão e grava no mesmo passo — evento tardio ou reentregue nunca sobrescreve estado mais novo

  4. 04

    Notificação deduplica pelo id do evento com SET NX EX — entrega é pelo menos uma vez

  5. 05

    Stream em vez de Pub/SubReceptor offline não perde evento, retoma da posição do grupo; MAXLEN ~ limita a retenção

  6. 06

    O Redis roda com AOF (appendfsync everysec): o stream é estado, não cache

Trade-offs

O que se ganha, o que se paga

4 vantagenscada ganho tem um preço4 custos

Vantagens

  • Receptor autônomo — responde com a origem fora do ar

  • Zero chamada de volta por evento

  • Receptor offline alcança o que perdeu pelo stream

  • Auditoria: cada evento é o fato completo

Custos

  • Payload maior em todo evento

  • Schema do evento acopla emissor e receptores

  • Réplica é eventualmente consistente

  • Dado sensível chega a todo receptor — filtre com content-filter

apps/messaging-streaming/event-carried-state-transfer

7 arquivos

src/

  • event_account.tsEnvelope CloudEvents, schemas do estado da conta e da transação, XADD e leitura por consumer group
  • replica_report.tsRéplica de relatórios em Hash com guarda de versão atômica em Lua
  • notification_transaction.tsNotificação ao cliente com deduplicação por id do evento
  • config_account.tsVariáveis de ambiente validadas no boot
  • replica_report.test.tstesteIntegração com Redis real: réplica completa, limite de versão, corrida, receptor offline, grupos independentes e deduplicação
  • demo.tsdemoPublica, derruba e religa relatórios e consulta a réplica sem a origem

./

  • docker.shinfraSobe o Redis 7 com AOF na porta 6379

Executar · com Docker

  1. ./docker.sh up# sobe Redis
  2. cp .env.example .env# variáveis de ambiente
  3. bun install# dependências
  4. bun run demo# roda o cenário
  5. bun run test# integração contra o serviço real
Requisitos
BunDocker
Sobe junto
Redis

Por que se relacionam

Teste rápido

Qual é o próximo passo depois de Event-Carried State Transfer?

Próximo projeto · Comunicação & MensageriaEvent Collaboration
Esc

↑ ↓ navegarEnter abrir191 resultados