Pontos Principais
-
Em que cenários eu deveria utilizar Feature Toggle?
-
O que são Canary Releases e Testes A/B?
-
Qual o tempo de vida de uma Feature Toggle?
-
Conheça e aprenda a criar Features Flags com o Flagr
Feature Toggles e Feature Flags com Flagr
Nos bastidores da entrega de uma nova feature, uma extensa esteira de testes, entre outras validações, é aplicada ao produto final. A depender do tamanho do impacto da feature no negócio, até mesmo outras validações são feitas antes mesmo do seu primeiro rascunho. Contudo, como estamos cansados de saber, quando o sistema está "ao vivo", a coisa muda de figura.
Uma condição não prevista ou um grupo focal de pesquisa inadequado podem levar a soluções inadequadas. Resultado: o produto pode ir do hype para o esquecimento. Seria muito útil se houvesse uma forma de, sem precisar redistribuir a aplicação, essa nova feature fosse desativado, dando espaço para o algoritmo antigo. Como se houvesse um botão liga-desliga, sabe? Esse botão é o que chamamos de Feature Toggle.
Feature Toggle
Apesar do estrangeirismo, a técnica é antiga. Quem nunca leu uma configuração de um arquivo .ini e colocou uma condição dentro do código?
if(!moduloXPTOHabilitado)
{
throw Exception(“Módulo XPTO não está habilitado”);
}
return new ModuloXPTO();
Este é o princípio básico do funcionamento de feature toggles, que também são conhecidos por feature flags. Particularmente acredito que faça mais sentido chamar feature toggle o padrão comportamental que liga/desliga uma feature. E chamar feature flag esse objeto que contém informações sobre a alternância de features.
Sim, você leu corretamente: objeto. Uma feature flag, ainda que possa armazenar valores binários (true/false), demonstra o seu real poder quando é enriquecida com maiores detalhes. Afinal, nem sempre você quer apenas dois estados para a feature flag. Pode ser que, dependendo do contexto, você almeje que apenas uma parcela dos usuários do seu software utilize a nova feature. Isso é especialmente verdade quando estamos trabalhando com canary releases.
Canary releases
Assim como os canários eram utilizados nas minas de carvão para acusar a presença de gases tóxicos, as canary releases servem para mostrar, em menor escala, problemas decorrentes da entrega de novas features. Assim, no momento em que a flag for resolvida, ela deve levar em consideração o contexto: quer seja do usuário, da aplicação ou ambos. Desta forma dados como geolocalização, idade ou qualquer outra informação que a aplicação tiver acesso pode ser utilizado como condição para habilitar (ou não) uma feature.
É justamente por isso que você já deve ter passado pela situação do seu aplicativo/site/software estar em uma versão diferente da pessoa que senta ao seu lado. Pode ser que você (ou o seu servidor) tenha sido escolhido como "canarinho" da nova versão. E se além de dados operacionais (se tudo funcionou ou se alguma coisa está prestes a quebrar), a aplicação colher informações sobre o seu comportamento, o que, possivelmente, temos é o que chamamos de "testes A/B".
Testes A/B
De maneira bastante objetiva, os Testes A/B servem para medir a aderência de novas features. O posicionamento de um botão, a paleta de cores de uma view, as frases utilizadas em uma campanha de marketing, entre tantas outras, são exemplos de alterações que podem influenciar diretamente no faturamento de uma loja on-line ou até o posicionamento da marca em um determinado país.
Os Testes A/B, portanto, além de habilitar esta ou aquela feature, também acabam por colher vários dados comportamentais do usuário, definindo o sucesso (ou fracasso) das features e a sua continuidade dentro do sistema.
A esta altura você deve estar se perguntado: "E o que acontece com o código que não deu certo?".
O tempo de vida de uma Feature Toggle
Manter código é caro. Manter código que não está sendo utilizado é ainda mais caro. Ao utilizar features toggle, você pode se sentir tentado a deixar o código "desligado" por toda a eternidade. Isso não é bom. Os features toggle precisam ser mantidos. Alguém precisa apertar o botão de ligar/desligar. Imagine se o seu sistema tiver dezenas, centenas dessas?
Você pode estar utilizando as feature flags apenas para determinar se está na hora - ou não - de ligar uma feature. Quando ela não fizer mais sentido, apague a feature flag e também o código que ela desliga. Vai ser mais barato buscar no histórico do seu versionador de código do que manter aquele balde de lama que não irá mais servir pra muita coisa.
Mas pode ser que você esteja utilizando as feature flags de maneira mais persistente em seu código, onde ela atua como uma espécie de configuração do sistema. Para casos como esse, a minha dica é: não faça isso. Esse tipo de "vazamento semântico" - quando você usa uma coisa para uma finalidade diferente da que ela se propõe - pode gerar dores de cabeça no futuro. Lembra do Single Responsibility Principle? Também vale para ferramentas.
Como implementar no meu sistema?
Os tempos em que se guardava todas as configurações em um arquivo .ini já se foram. Em partes por motivos de segurança, mas também porque gerir a configuração de software manualmente é algo cada vez mais impensável. Especialmente em um contexto de micro serviços, em que você pode não saber onde e quantas instâncias do seu software estão rodando.
Por este motivo a gestão de configuração está cada vez mais automatizada. O que não seria diferente com as feature flags. Várias soluções, baseadas no modelo de micro serviços, estão disponíveis no mercado. Algumas pagas e outras open source e free. Para este caso eu destaco o Flagr .
O Flagr
O Flagr é uma ferramenta completa, no que diz respeito ao consumo de feature flags. Ele permite que você crie todos os tipos de flags que comentamos acima e algumas mais. Ele conta com uma UI que, no começo, parece um pouco confusa. Mas conforme você entende o funcionamento dele, o uso fica natural.
Além do código disponível no Github, o Flagr possui ampla documentação, ensinando o usuário a fazer desde a instalação, via Docker images ou buildando a aplicação localmente, até o uso da API via requisições HTTP REST ou utilizando os SDK disponíveis. Também estão disponíveis a documentação da API e um blog trazendo mais detalhes sobre a implementação do Flagr, suas possibilidades e casos de uso.
Como podemos criar uma feature flag com Flagr?
Você pode seguir os links anteriores para instalar o Flagr localmente, mas também tem a possibilidade de utilizar uma aplicação de testes disponível no Heroku. Ao acessar o link, você verá a GUI do Flagr:
Nesta primeira tela você tem disponível a lista de flags criadas, data de modificação e se ela está habilitada ou não. Já na parte superior, você tem uma caixa de texto com o place holder "Specific new flag description". Digite o nome da sua nova flag e clique em "Create new Flag". Para o nosso exemplo, a nossa flag será: "Dominar o mundo". ATENÇÃO! A nova flag será adicionada na tabela de listagem. Cuidado para não clicar várias vezes no botão.
Clique na nova flag criada. Agora será possível editar suas configurações. Vamos conhecer cada uma das seções da flag, começando pela que a identifica:
No container principal desta seção, você conta com três campos:
- Flag ID: Um inteiro, auto-incremental, que identifica a flag;
- Flag key: Uma chave que também pode ser utilizada para identificar a flag;
- Flag Description: Uma descrição amigável para que o usuário do Flagr possa saber do que aquela flag se trata.
Como é muito mais fácil, na aplicação, gerir um texto amigável, vamos alterar a nossa Flag Key para "DominarOMundo", vamos habilitar a flag (no toggle no canto superior direito) e por fim, salvar as alterações no botão "Save Flag".
Flagr: Variants
A seção "Variants" inclui os possíveis valores de retorno quando uma flag for solicitada. Para incluir uma nova variante, digite um valor (alfanumérico) na caixa de texto com o placeholder "Variant key" e clique no botão "Create Variant". Como exemplo utilizamos a palavra "Yes".
Após ter criado a sua primeira variant, vai perceber que uma nova opção fica disponível: Variant attachment. Ao clicar neste label, o Flagr irá abrir uma caixa de texto onde você pode incluir um payload no retorno da flag. Você pode adicionar o conteúdo que quiser, mas caso opte por adicionar um json, por exemplo, poderá desserializar o conteúdo no aplicativo que requisitou a flag (enriquecendo ainda mais o uso da flag).
Flagr: Segments
Para que você possa entender para que servem os segmentos, você precisa saber de antemão que, ao requisitar o valor de uma flag ao Flagr, o software precisa enviar alguns dados de contexto (Entity Context) de modo que o Flagr possa saber que variant retornar. Por exemplo, vamos supor que uma flag estará disponível apenas para usuários do Estado do Paraná. Neste caso, ao solicitar uma flag, a aplicação enviaria no contexto a UF do seu contexto. E com base nisso, o Flagr decide qual variant retornar ou ainda com que frequência a variant deve ser retornada para aquele contexto (lembra dos testes A/B?).
Vamos criar o primeiro segment, clicando no botão "New Segment".
O pop-up que abre solicita que seja informada uma descrição para o segmento e uma taxa de repetição. Para o nosso exemplo coloque 100. Assim sempre que aquele segmento for selecionado, ele irá retornar a variant configurada.
Após criar o segmento, várias novas opções ficam disponíveis:
Flagr: Segments: Constraints
Na subseção constraints definimos de fato o segmento, aplicando quantas regras forem necessárias ao contexto. Para o nosso exemplo, vamos assumir que o Entity Context, enviado pela aplicação cliente, sempre terá um campo "UF" com a uf do estado do cliente. E quando o cliente for do Paraná, a flag deverá retornar a variante "YES". Do contrário, deverá retornar a variant "NO". Veja como ficou:
E no botão distribution, você determina a distribuição das variants (para entender melhor a diferença entre rollout e distribution, veja a documentação:
Agora você pode optar por criar um novo segmento onde os usuários são oriundos de SP, ou diferentes do PR e acima de 21 anos. Da maneira que você quiser.
Para o nosso caso, talvez você pense que seria uma boa ideia assumir que "vou retornar um valor padrão para caso o Flagr não encontre nenhum segmento para o contexto que eu enviei". Eu tomaria essa decisão em último caso. Seria bastante interessante você logar esta ocorrência e entender os motivos de nenhum contexto estar contemplado. Você pode estar presumindo erroneamente uma situação e gerando mais problemas que soluções.
E o Flagr está pronto para uso.
Testando nossa nova flag
Se você quiser, pode utilizar aplicativos como o Postman ou Insomnia. Mas caso não os tenha instalado, tudo bem. O Flagr dispõe de uma seção "Debug" que já traz tudo quase pronto pra você. Clique em Evaluation:
Como pode observar, a requisição está quase pronta. Vamos apenas adicionar os dados de contexto que precisamos e clicar no botão Post:
Ao habilitar a propriedade "enableDebug" no request, o Flagr irá incluir uma série de mensagens no response. Assim você sabe exatamente como eletomou a decisão para aquele segmento específico. Muito útil para testes, mas só vai inflar o seu response em produção.
E como implementar na prática?
Este é um papo que vai ficar para o próximo artigo, em que implementaremos feature toggles com C#. Espero você lá!
Francisco Thiago de Almeida é desenvolvedor há 15 anos, com experiência em vários segmentos públicos e privados. Faz parte do DevParaná, coordenando meetups e também integra o comitê técnico da DB1 Group. É pós-graduado em arquitetura e desenvolvimento de software na plataforma .Net e integra o time de pessoas desenvolvedoras da DB1 Global Software.