Executando verificação de segurança...
4

Horror Story Saga: Assíncrono, Atômico e Coreografado

No conjunto de diferentes variações de Sagas em microserviços, o Horror Story Saga representa um padrão em que a comunicação é assíncrona, a busca de atomicidade predomina na transação e a coordenação ocorre via coreografia, sem um orquestrador central. Neste artigo, analisamos como esse modelo funciona, seus desafios e em que cenários pode ser aplicado.


1. Visão Geral

  1. Comunicação Assíncrona
    • Em vez de chamadas síncronas bloqueantes, cada serviço interage por meio de mensagens, eventos ou filas, não aguardando resposta imediata para prosseguir.
  2. Atômico (“tudo ou nada”)
    • A proposta é que todos os serviços envolvidos cheguem a um estado único de confirmação ou revertam integralmente, aproximando-se de uma transação distribuída atômica.
    • Implica uma forma de “prepare & confirm” ou “rollback”, mesmo sem coordenação centralizada.
  3. Coreografia
    • Cada serviço decide o momento de executar seu passo, reagindo a eventos ou mensagens. Não há um orquestrador único que dite a ordem ou gerencie confirmações globais.
    • Os serviços devem conhecer as regras de como sinalizar “pronto para confirmar” e como detectar se algo falhou e exige compensação.

A analogia “Horror Story” indica que, embora a meta seja manter atomicidade, a ausência de um orquestrador pode gerar cenários complexos, exigindo maior atenção no controle de fluxos e compensações em um contexto essencialmente distribuído e reativo.


2. Como Funciona?

2.1 Publicar e Assinar (Pub/Sub)

A comunicação entre os microserviços tende a acontecer via tópicos ou filas, usando métodos assíncronos. Por exemplo:

  1. Serviço A publica um evento “Início de Transação” ou “Operação Solicitada”.
  2. Serviço B escuta esse evento, processa sua parte e publica um “B Pronto para Confirmar” ou “B Falhou”.
  3. Serviço C ou outros serviços reagem ao estado de B e assim sucessivamente.

2.2 Tentando Atomaticidade

Para aproximar-se de uma transação de estilo “tudo ou nada”, cada serviço:

  • Registra internamente o estado “PENDING” quando recebe o pedido para efetuar sua operação.
  • Publica um evento de sucesso ou falha após concluir a operação local.
  • Aguarda a confirmação global (se todos os serviços envolvidos publicarem algo como “Pronto para Confirmar”), e só então “commita” definitivamente.
  • Se notar falha em algum serviço, inicia a compensação local (desfazendo operações pendentes) e publica um evento de rollback.

2.3 Coreografia das Decisões

Não há um orquestrador único que compile todas as respostas. Em vez disso, cada serviço monitora o “estado global” via eventos. Se um deles detectar, por exemplo, que outro serviço falhou, pode disparar sua compensação ou alertar os demais. A consistência final depende de todos convergirem para “commit” ou “rollback” na presença das mensagens certas.


3. Exemplo Simplificado

Imagine três microserviços: A, B e C, cada um responsável por parte de uma transação (por exemplo, A = Pedido, B = Pagamento, C = Estoque). O fluxo poderia ser:

  1. A publica evento “Iniciando Transação X”.
  2. B recebe, executa a operação localmente, marca status “PENDING-B”, e em caso de sucesso, publica “B Pronto” (ou “B Falhou” se algo deu errado).
  3. C executa a mesma lógica, publicando “C Pronto” ou “C Falhou”.
  4. A e “todos” os demais serviços escutam esses eventos.
    • Se detectarem que B e C publicaram “Pronto”, A publica “Commit Global” (ou B ou C poderiam também publicar esse commit se a regra permite).
    • Todos leem “Commit Global” e transformam seu status de “PENDING” em “COMMITED”.
    • Se surgir um “Falhou” de algum participante, cada um dispara rollback local e publica “Rollback Concluído”.

Sem orquestrador, cada serviço precisa conhecer a lógica de eventos e estados para saber se já pode ou não confirmar ou reverter.


4. Desafios

4.1 Complexidade de Coordenação

Sem um componente central, é necessário definir claramente:

  • Quais eventos sinalizam sucesso ou falha?
  • Quem publica o “commit global”?
  • Como cada serviço sabe que o processo está encerrado?

A ausência de um coordenador impõe que cada participante conheça a “dança” de eventos e a semântica de confirmação.

4.2 Gestão de Erros e Reconciliação

Mensagens podem ser perdidas, duplicadas ou entregues fora de ordem. Cada serviço deve ser idempotente e preparado para situações em que recebe eventos tardios (por exemplo, um “Falhou” depois de ter finalizado um “Commit”).

4.3 Tentando Ser Atômico em Ambiente Assíncrono

Implementar atomicidade num ambiente em que cada serviço confirma localmente e depende de eventos externos para saber se deve “commit” ou “rollback” é um grande desafio. O sistema pode requerer reprocessamentos ou mecanismos de reconciliação caso alguns eventos fiquem “no limbo” por atrasos na entrega ou falhas prolongadas.


5. Benefícios Potenciais

  • Alto Desacoplamento: Cada serviço se comunica via eventos, sem depender de um orquestrador único.
  • Escalabilidade: A arquitetura pode distribuir a carga de forma mais horizontal, pois cada serviço reage aos eventos de acordo com sua função.
  • Flexibilidade de Evolução: É possível adicionar ou remover participantes do fluxo, desde que novos eventos ou tópicos sejam ajustados, sem refatorar um orquestrador central.

6. Ilustração em Diagrama

flowchart LR
    A((Serviço A)) -- publica "StartTx" --> Broker[Broker de Mensagens]
    B((Serviço B)) -- escuta "StartTx" --> B
    B -- "B Pronto" --> Broker
    C((Serviço C)) -- "C Pronto" --> Broker
    Broker -- "Eventos B/C" --> A
    A -- "A Falhou" ou "A Pronto" --> Broker
Broker -- "Commit ou Rollback" --> A
Broker -- "Commit ou Rollback" --> B
Broker -- "Commit ou Rollback" --> C

Cada serviço se inscreve e publica eventos no broker, tentando coordenar atomicidade por meio das mensagens de “pronto para confirmar” e “falha”.


7. Conclusão

O Horror Story Saga (Assíncrono, Atômico, Coreografado) descreve uma abordagem desafiadora para manter um modelo “tudo ou nada” em arquiteturas distribuídas, sem orquestrador central. Os serviços:

  1. Trocam eventos de “prepare”, “pronto” ou “falha” para tentar sincronizar o estado.
  2. Executam compensações caso detectem falhas, publicando também eventos de rollback.
  3. Convergem a um estado final (“commit” ou “abortado”) com base na eventual recepção e processamento dessas mensagens.

Esse padrão demanda concepções sólidas de controle de fluxo, tolerância a erros e garantias de entrega de mensagens. Quando bem implementado, pode oferecer alta escalabilidade e desacoplamento — porém exige cuidado redobrado para evitar situações em que a “história de horror” seja a dificuldade de manter coerência e rastrear cada passo do processo em meio a eventos potencialmente fora de ordem ou duplicados.

Carregando publicação patrocinada...