Sistemas Reativos cover

Sistemas Reativos

Capítulo 1: Um discurso de ódio à proatividade

25/May/2018
7 minutos

Em Shrek 2, há uma cena tão irritante quanto clássica que consiste no Burro Falante perguntando de modo insistente: “a gente já chegou?”. O animal tagarela está ansioso para chegar a Tão Tão Distante e não consegue conter a empolgação.

A frequência da indagação e a inquietação do Burro aborrecem (hehe) o ogro esverdeado. Honestamente, não lembro bem como o Shrek responde — tampouco você, admita — mas presumo, enquanto julgo o azucrinante asno, que seja algo natural e sagaz como: “ainda não. Aviso quando chegarmos”.

Confira comigo no replay:

Tal resposta seria uma resposta sagaz porque seria uma situação em que todos sairiam ganhando: o Burro saberia quando chegasse e o Shrek poderia apreciar seu sossego calando o desagradável companheiro de viagem. Seria também uma resposta natural pois é algo simples e vem rapidamente à cabeça de todos nós. Todos já passamos por isso, não?

Apesar de reconhecermos que o Burro não está sendo esperto, replicamos esse comportamento na nossa arquitetura de microsserviços.

Sem querer ofender ninguém, muito menos a personagem caprina/ovina/suína/divina (?).

Se você assistiu ao vídeo (o que eu duvido, porque eu não assistiria se fosse você) você percebeu que a resposta do Shrek não é tão astuta assim, reforçando o estereótipo ogro já estuporado que vemos ultimamente nas ruas por aí.

Trabalhemos em cima do seguinte, contudo não incomum, cenário.

Não incomum cenário

Em um e-commerce, porque todo exemplo exige um e-commerce, construído sob a filosofia de microsserviços, é comum termos um microsserviço para encapsular o domínio de preços e um outro para tratar do domínio de produtos.

Por haver uma íntima relação entre os domínios — e porque HTTP é supervalorizado — é natural pensar em expor um endpoint HTTP na aplicação de preços em que, dado um determinado identificador de produto, o preço do produto é retornado.

Assim, sempre que o sistema de produtos precisar recuperar o valor de uma dose de café, o serviço de preços estará a disposição para atendê-lo.

O que pode acarretar em uma indagação frequente, consumindo recursos e tirando a paciência do sistema proprietário do dado.

Pausa dramática para reflexão…

Notaram alguma semelhança?

O problema consiste em, assim como o sr. Burro Falante, tentar recuperar informação proativamente. Pergunta retórica: o que aconteceria se o sistema detentor da informação, Shrek/serviço de preços, estivesse indisponível/tivesse batido as botas? Há uma certa ingenuidade, e falta de noção, em perturbar a paz de espírito de um terceiro para obter a informação.

Imagine se existissem duas instâncias de Burro Falante desejando a mesma informação e atazanando o juízo do açucarado e pacífico Shrek? E se escalássemos o Burro Falante para termos três/múltiplas instâncias? E se um outro animal/serviço também precisasse dessa informação? O mundo sucumbiria! Coitado do Shrek…

Estou cada vez mais tentado a acreditar que solicitar uma informação nunca é uma boa ideia.

Diga, não peça

Eu não sou o primeiro a pensar assim. Tell, don’t ask (Diga, não peça, traduzido precariamente do inglês) é um princípio que ajuda as pessoas a se lembrarem que a orientação a objetos é sobre empacotar dados com as funções que operam naqueles dados.

Melhor do que requisitar dados a um objeto, é instruir o objeto que possui os dados ao que fazer, encorajando a encapsular comportamento dentro do objeto que contém o dado.

Eu sei, esse é um princípio da orientação a objeto, o que não é necessariamente um problema. Os princípios SOLID, DDD, e “alta coesão e baixo acoplamento” também não são sobre microsserviços, no entanto, os valores extrapolam o propósito original e os utilizamos como diretrizes mesmo assim.

HTTP GET

Eu tento não citar, mas é mais forte do que eu e preciso desabafar. Quem me conhece sabe o ódio carinhoso que nutro por este bendito método HTTP. Podem me chamar de radical, mas não consigo ver forma adequada de utilização desse método.

Salvo quando há exigências, como é o caso de quando se utiliza o browser e suas repercussões ou quando se necessita consumir uma API de terceiros que só expõe esse maldito, entre outros. Mas voluntariamente expor um recurso via GET…

Além de ferir o princípio “tell, don’t ask**”**, o GET ressalta uma das duas dificuldades da computação: nos expressar claramente. Afinal de contas, qual o significado real da palavra “get”? — Segundo esse estudo, “get” possui incontáveis 289 significados.

Cache para que te quero?

Mas você pode argumentar: solicitar uma informação pode não ser tão ruim. Ainda mais se a resposta da solicitação for idempotente. O que nos permitiria fazer cache da informação para otimizar o desempenho.

É como se o Shrek anotasse “não” em um papel, e sempre que o Burro Falante perguntasse, a folha com a resposta seria exibida pelo ogro. O que pouparia tempo e raciocínio.

Se você argumentou isso, excelente. Mas a invalidação do cache não é algo trivial. É, inclusive, a segunda dificuldade da computação. Em que momento o Shrek atualizaria a resposta no pedaço de papel?

Uma alternativa para facilitarmos a invalidação do cache é: aceitá-lo como válido e o atualizássemos quando explicitamente ordenado. Em outras palavras, e se o Shrek dissesse ao Burro: “a resposta será sempre “não”, até que eu diga o contrário”?

O cache seja louvado

Em um cache onde a informação nunca é inválida, o dado estaria sempre acessível sem precisar da consulta em um outro sistema (evitando um HTTP GET da vida. Deus é mais!). Poupando qualquer participação do Shrek.

Retornando ao exemplo dos microsserviços de preço e produto: se o microsserviço de produtos já possuísse a informação de preço do ingrato café, esse dado não precisaria ser recuperado em outro sistema, favorecendo a autonomia e enfraquecendo o acoplamento. Pontos extremamente positivos e chave em uma arquitetura de microsserviços.

Isso nos leva a outros dois questionamentos: 1) como obteríamos a informação inicial? e 2) como atualizaríamos esse valor?

A resposta das duas perguntas é a mesma: o sistema de preços diz o preço dos produtos sempre que houver uma alteração. O serviço de produtos, por sua vez, reage ao envio da alteração e replica essa informação, adaptando-a a sua ótica.

É como se o Shrek instruísse o sr. Burro Falante de tal forma que o sorridente equino fosse capaz de responder sua própria pergunta.

Como se não fosse suficiente, ainda poupamos a mensagem que solicita os dados, a própria fala: “a gente já chegou?” não existe mais. Fazendo com que evitemos gastos desnecessários e melhoremos o desempenho.

Sistemas reativos

Percebem onde chegamos (além de ao reino de Tão Tão Distante)?. Chegamos à resposta que o Shrek deveria ter dito: aquela que julgamos sagaz e natural.

A gente já sabia esse tempo todo, ainda assim, não costuma aplicar nos nossos sistemas.

Para chegar a tal solução tivemos que mudar a perspectiva com a qual vemos o cenário: a perspectiva reativa (não confundir com respectiva).

Diga não à proatividade

Resumindo, para alcançar a reatividade, tivemos que parar de, proativamente, importunar um outro sistema e passar a reagir quando a informação que estou interessado é recebida. De quebra, além de sossegarmos o facho e deixarmos o outro sistema em paz, ganhamos uma maior autonomia e um acoplamento mais fraco, e evitamos a requisição que solicita uma resposta. Só vi vantagens. Oh yeah, baby.

Todavia, como um dos contras dessa abordagem, temos a consistência eventual.

O que acontece se o microsserviço de preços atualizar o valor do café e essa informação não foi recebida pelo sistema de produtos? Ou o que aconteceria se Tão Tão Distante mudasse de localização e o Shrek não pudesse comunicar isso ao Burro Falante? A informação obsoleta poderia acarretar em uma série de problemas…

Eventualmente, em um futuro não tão tão distante, falarei mais sobre isso. Spoiler alert: consistência é uma ilusão. A inconsistência é inevitável, seja em um sistema reativo ou não.

Concluindo

Esse é o principal conceito por trás da reatividade. Bem simples, não é? Mas existe muito mais para ler. Alguns outros conceitos e implicações surgem por conta dessa adoção. Clique no segundo texto da série para ler mais sobre eles:

Este texto serviu de base para um capítulo do meu livro. Se você gostou do texto, considere adquirir o livro.

Já que você tá por aqui, dá uma olhada nesses aqui também: