E a gente foi para muitos rascunhos, e chegou nesse primeiro desenho aqui sobre, como a gente vai desenhar isso.  O SAGA é um padrão de projeto para fazer esse tipo de controle de transação distribuída e ele tem duas formas principais de integrar, fazer essa questão de coordenar o que está acontecendo. 

A primeira seria por uma orquestração, onde você tem um microsserviço principal, um serviço, como você quiser chamar, que vai mandar mensagem para o primeiro serviço. O serviço A, faz isso aqui, manda a mensagem. Ele espera a resposta do serviço A… o curioso é que isso poderia ser até síncrono também, poderia chamar um http do serviço A, e esperar a resposta e chamar o próximo, também seria ao pé da letra um SAGA. Mas a gente vai para a parte de mensageria, por todos os motivos de escala depois. Mas vai lá, chama o B, chama o C e assim por diante. 

Ou a coreografia em que alguma coisa só manda, serviço A faz o que tem que fazer. E o serviço A “sabe” que ele precisa chamar o serviço B. A parte do “sabe” é uma das partes que me incomodava muito em todas as literaturas. E eu falava: “ah, como raios ele sabe? Como assim? Sabe de onde? Tira de onde as informações?” E isso não fica claro quando você está lendo no primeiro momento as coisas. 

Colocamos aqui, esse INIT nada mais é do que uma API, na verdade, que então tem alguma camada aqui antes, chamou a API, que seja. A API está bem escopada, é  uma API nova. Então, eu tenho o que é para ser feito naquele endpoint. Ele vai mandar mensagem aqui para o sistema de filas, a mensagem para que o primeiro passo A, B e C possam pegar. Então teria aqui:  manda para o tópico A. O A quando terminar vai mandar para o tópico B. o B quando terminar vai mandar para o tópico do C. Aquela questão que nós estávamos falando sobre muito…com isso daqui ficou legal, mas isso aqui não tem muito a ver com literalmente saber o estado das coisas. A nossa ideia aqui foi: vamos convencionar. A gente convenciona isso daqui, tem segurança de que pela API de entrada eu sei quais passos tenho que fazer. Eles estão muito bem descritos. Tem responsabilidades bem definidas para cada serviço. Se eu fizer um monitoramento das filas, eu vou saber por onde uma mensagem passou porque eu tenho ID da mensagem, o ID da transação que seja. E eu vou olhar: a transição A passou. Passou no tópico  A, no B e não no C. Então, eu tenho o estado e veio a questão do GSM, esse Global System Management, que a gente tanto precisava para o controle mesmo das coisas e estabilidade da plataforma, porque mais do que… a questão aqui é muito mais do que erros não podem acontecer. Não.  Erros vão acontecer e quando acontecerem a gente precisa saber onde aconteceu para conseguir reagir. 

A partir daí, a partir de analisar as filas, salvar numa base a gente pode monitorar isso para tomar as ações. Porque as ações tanto podem ser de avisar alguém, porque simplesmente é um erro novo que não sabemos o que fazer. Dá um alarme, seja num sistema de backup, Slack, e-mail ou reenfileira isso fazendo… ou mandando retry, por exemplo, nesse caso falando que passou no serviço A, no serviço B e não no serviço C. Então faz uma retry do C, tenta de novo primeiro vai que o  C só está fazendo pause  ou alguma coisa está mal gerenciada ali de um ack da mensagem não tratou. Reenfileira, coloca na fila de novo fazendo retry. Ou um compensate que vem da parte sobre as rotinas de compensação, que é esse rollback distribuído também. 

E a ideia seria que passou com sucesso no A, passou no B e deu um erro no C, eu posso fazer também o rollback distribuído desde que eu tenha, que eu garanto a idempotência em cada nível de serviço, que é mega importante aqui tanto para o caso de eu ter um “sanduíche de rede” de qualquer problema que eu que eu tenho duplicidade de mensagens ou coisas assim, quanto para eu ter segurança de se eu não sei o que aconteceu. Reprocessa para mandar outra mensagem, porque quem processou vai processar de novo e quem não processou vai processar e fica tudo certo. Está aí a beleza da idempotência. E a rotina de compensação é justamente o conceito de que eu vou voltar, eu tenho a forma de fazer o rollback distribuído e eu posso inclusive, se eu tenho de idempotência, mandar a mensagem de rollback várias vezes também, porque quem não fez vai fazer e quem já fez vai fazer de novo. 

Tudo é muito legal. É muito bacana de rascunho para a gente entender e ficar discutindo: vamos trabalhar aqui a coreografia, nessa parte de baixo escolhemos aqui quem seria a nossa mensageria. Fomos lá fazer a pesquisa do que se encaixaria bem. O Kafka se encaixava bem no nosso cenário aqui. Foi bem interessante, porque também tem muito material e ferramenta em Java de Kafka e não em GO. A gente teve alguns percalços na integração.