Escolar Documentos
Profissional Documentos
Cultura Documentos
Índice
Dedicar tempo para resolver problemas
Quando os valores atrapalham 1
O problema do modelo de Squads 2
O problema dos PDIs 2
Medindo as pontas
Não se gerencia o que não se mede - William edwards 4
Observabilidade 4
Testes de Carga 5
Medindo o banco de dados 5
Testes automatizados
Testando o que é crítico 6
Testando as configurações 7
Testando o que não é crítico 7
Usar o Lúmen
Bom de um lado ruim de outro 8
Existem muitos e muitos problemas importantes a serem resolvidos, porém nunca sobra tempo
para resolvê-los. O time aumenta e ao invés de sobrar tempo pra mexer nesses problemas que
são muito importantes, o trabalho duplica, triplica, é multiplicado por cinco, e as coisas só pioram.
Vejo que com a falta de tempo para focar em problemas técnicos, usa-se o PDI para tentar suprir
essa necessidade, e isso acaba acarretando alguns problemas;
Primeiro, referente à questão ética, de resolver os problemas da empresa no seu tempo livre, se
cobrar por isso e encarar como prazo. É totalmente errado ao meu ver.
Acredito que é extremamente necessário existir uma folga em cada tarefa para que seja feito um
planejamento, para que haja espaço para fazer uma refatoração, e que haja espaço para trazer
coisas novas, e espaço para focar em atributos arquiteturais como qualidade, performance,
segurança, escalabilidade, disponibilidade, resiliência, etc.
Tudo é tratado como urgência e nunca existe tempo para resolver problemas que não são
exclusivamente da entrega, da meta que está sendo cobrada a ferro e fogo.
Quando você está trabalhando em uma tarefa, e aparece uma urgência e você precisa passar
alguns dias mexendo em outra, o prazo, da tarefa que você precisava entregar deve ser
alterado. E é algo que eu vejo que não acontece aqui. Isso faz com que estejamos
constantemente ainda mais desesperados do que o comum, visto que não queremos prejudicar
a empresa de nenhum lado e isso acaba por fazer com que as pessoas parem de ajudar umas as
outras, visto que se tomarem um dia ou dois em resolver algo, que pode ser mais prioritário,
com certeza vai prejudicar muito a outra “deadline” e isso vai virando uma bola de neve.
QA
Sempre que fazemos um projeto, existe uma etapa de QA manual, feita por pessoas de fora do
time, geralmente as quais pediram tal projeto. Isso é uma prática que ajuda o time a entregar
algo com uma maior qualidade, porém existem alguns problemas aqui;
Sempre é dimensionado um tempo para ser entregue o projeto, ignorando a etapa de QA. E
geralmente trata-se como se ela não fosse existir, o que na prática, sempre leva a atrasos.
O processo de QA geralmente tem muitas alterações, algumas até mesmo de escopo, o que leva
muitas vezes a literalmente ter que refazer algumas coisas por inteiro, o que leva tempo, tempo
esse que deveria ser dimensionado e levado em consideração em todos projetos.
Acredito que os prazos deveriam ser dimensionados de acordo com a entrega de incrementos,
e que o processo de QA fosse feito e os prazos redimensionados depois da entrega de cada
incremento, pra se ter uma certeza maior da entrega.
Muito se fala em implementar métodos ágeis, mas não adianta nada se o modelo de dimensionar
prazos se manter o mesmo do cascata.
Medindo as pontas
Não se gerencia o que não se mede - William edwards
Existe um grande problema aqui ao meu ver que é a falta de medição de performance,
qualidade, rastreabilidade e demais medições sobre as múltiplas faces do código.
Eu comecei a tentar dar atenção para esses pontos num PDI pessoal, pelo lado do Frontend, porém
pelos motivos que destaquei acima e outros pessoais não consegui focar, achar tempo pra focar
nesses pontos, os quais acredito que devem continuar sendo trabalhados.
Testes de Carga
É realmente importante saber como nossas aplicações vão performar quando o volume de
dados, usuários simultâneos e o volume muda. Assim como saber a velocidade em que as
aplicações respondem, como se comportam em momentos de stress, e saber a latência em
diferentes cenários. Para isso existem ferramentas open source como o Locust ou ferramentas
mais avançadas como o K6 por exemplo que conseguem trazer uma experiência legal nesse
ponto.
Testes automatizados
Testando o que é crítico
Outro problema, um dos mais sérios que eu vejo hoje, é a falta de testar partes críticas do
software. Sei que é impossível testar tudo, porém aqui, principalmente no backend, trabalha-se
com pontos muito críticos, coisas muito importantes, e não sei como conseguem mexer nesses
pontos sem estarem cobertos por testes.
A XP, eXtreme Programming, estabelece ferramentas para lidar com um conceito chamado
“Coragem”, no qual, um desenvolvedor precisa ter coragem de mexer no código sem ter medo
de dar problema. Para isso ferramentas como backup, controle de versionamento de código (git)
e testes automatizados são cruciais.
Acredito realmente que deveria ser feito um esforço imenso para cobrir todas as partes críticas
com testes, independente se metas não forem cumpridas para tal.
Testando as configurações
Sempre que alguém precisa configurar algo para funcionar, geralmente segue a documentação,
e sempre que necessário consulta o Google, Github issues e semelhantes e vai tentando até dar
certo. Isso é um processo comum, e ele e suas variações são muito bem válidas.
Entretanto, é necessário depois desse processo, entender o que cada configuração faz e o
porquê de ela estar ali, no que ela influencia e etc.
Para isso, usar testes de configuração é uma coisa que garante que os demais desenvolvedores
possam mexer nas configurações sem que outras coisas parem de funcionar.
São os testes mais simples de serem feitos, mas também os mais negligenciados. Acredito ser
extremamente importante começarem a dar uma atenção especial para essa parte.
No começo essa cultura vai diminuir a produtividade, o que aqui na Playkids é considerado
quase como um pecado. Porém é necessário em algum momento dar uma atenção nessa
transição e literalmente mudar seu conceito referente a testes.
Os benefícios que os testes dão a médio e longo prazo valem a pena, e mesmo que num
ambiente em que a urgência das entregas seja excepcional, vale a pena investir nessa parte.
Entretanto, um dos meus maiores pesares é não ver esperança de que isso aconteça, portanto
acredito que se puderem se focar ao menos nos testes de coisas críticas, os de configuração e
os de carga, as coisas podem mudar muito por aqui.
Usar o Lúmen
Bom de um lado, ruim de outro
Uma coisa que eu sempre gostei do Laravel é que ele tem uma documentação incrível, tem
muito conteúdo nas issues do Github e também tem muitos pacotes extensores da comunidade,
que auxiliam e muito o desenvolvimento. Ele também tem muitas atualizações de segurança, e
por ser inspirado no Ruby on Rails, segue boas convenções e mesmo que a comunidade PHP
não se preocupe com as mesmas coisas que a comunidade Rubista, acaba que alguns
conhecimentos acabam se transferindo de um universo para o outro.
Nesse ponto é que entra a parte de desenvolver uma aplicação apenas com a parte de API, o
que no Rails fazemos com um simples prefixo --api e alguns parâmetro de exclusão de módulo,
como --skip-turbolinks ou --skip-sprockets por exemplo. O Laravel também decidiu adotar uma
abordagem para o mesmo destino, mas seguindo caminhos totalmente diferentes.
A comunidade Laravel decidiu fazer isso criando um projeto a parte chamado Lúmen, o qual não
tem dependência direta com o Laravel. Ambos não são mantidos pela mesma equipe, e não
seguem os mesmos padrões, tal como seus mantenedores têm filosofias diferentes para o futuro
e rumo dos projetos.
Tendo isso como base, diferente do Rails, em que você pode adicionar os pacotes que
necessitar, conforme a aplicação for crescendo, no Lúmen, muitos pacotes do Laravel
simplesmente não funcionam, tal como grande parte das bibliotecas externas, da comunidade,
não são compatíveis com o Lúmen, e, várias vezes seus mantenedores dizem abertamente que
não estão dispostos a resolver tais conflitos, ou alterar coisas no framework para que isso seja
possível.
Vejo como uma coisa ruim pois não vejo como saudável usar um framework com filosofia tão
diferente do seu predecessor, o Laravel.
Muitas vezes tive de desistir de usar algo que resolveria um grande problema ou ter que criar um
micro-serviço em Laravel que não seria necessário, apenas para utilizar um recurso ou outro sem
medo de dar conflito.
Mas é apenas uma opinião minha, eu removo os service providers do que não preciso e
desabilito o autocompletar para elas na ide.
“Qual o problema de falar o nome errado? As coisas não param de funcionar por causa disso!”
Sim, porém quando falamos o nome errado, acabamos ignorando o conceito que realmente ele
representa, e acabamos perdendo parte de um benefício que poderíamos estar tendo se
soubéssemos que ao menos tal conceito existe. Um exemplo: tratar SOLID como sendo separar
partes do código em diferentes pastas (ter uma pra services, outra pra helpers, outra pra styles,
por exemplo), perde todos os benefícios que cada letra do acrônimo de SOLID nos fornece,
como por exemplo Inversão de dependência para separar o código em múltiplas camadas ou
usar decorators para resolver o princípio de open/closed e ter códigos mais extensíveis, com
menos possibilidade de problemas em classes dependentes e com menos ctrl+c, ctrl+v, etc.
Porém frequentemente acontece de alguém criar uma tabela e não atualizar o dump, de
subirmos uma feature e esquecer de gerar aquela nova coluna no banco de dados de staging, e
no banco de dados de produção.
Migrations são uma coisa que nasceu na década de 90 para resolver esse problema e eu não
consigo entender como uma empresa em 2021 não utiliza ainda.
Sei que é um processo grande para mapear as tabelas do banco atual para migrations, porém
existem técnicas como criar um Snapshot do banco de dados e fazer migrations a partir daí, ou
até mesmo algumas ferramentas que auxiliam no processo como laravel-migrations-generator.
Ter migrations ajudaria no processo de criar testes automatizados, tanto como ter seeds e
factories para auxiliar no desenvolvimento destes, além de resolver o problema de portabilidade
de aplicações (já que já temos docker, mas ela não resolve de todo o problema, uma vez que
temos esse problema com o banco).
Existe uma arquitetura chamada Event Sourcing na qual você salva todos os históricos de
eventos aplicados sobre um determinado modelo, e no qual podemos ter esse histórico mais
preciso das ações desempenhadas no banco. Isso pode ser feito à nível de logs dentro do
SGBD, mas é algo extremamente difícil de ser feito e demanda um conhecimento e acesso de
muito alto nível no banco, o que para a LGPD pode não ser tão agradável.
Utilizar a idéia de CQRS para separar as queries das mutações, ajuda muito nesse caso,
garantindo um banco mais estável, tal como funciona como um encaixe perfeito para a
introdução de Event Sourcing na empresa.
Independência
Mensageria, Service Mesh, Service Discovery e Circuit Breaker
Outro problema é a falta de recursos de mensageria, que garantam uma comunicação
assíncrona e que garantam a independência e unicidade das aplicações.
Uma aplicação não deve falhar de solicitar uma ação caso a outra estiver fora do ar, as ações
devem ser enfileiradas e consumidas de forma assíncrona.
Diferentes instâncias devem ingressar no sistema sem que alguém precise ir lá e definir seu IP
pros consumidores conseguirem consumir delas.
Também é necessário poder rastrear os erros entre aplicações, tirar um aplicação da malha de
serviços se ela está sobrecarregada, repetir requisições que não conseguiram chegar a seu
destino, tal como controlar a saúde das coisas, e para isso tudo, esse conjunto de tecnologias se
completa
Event Mesh
Para o caso de decidir uma arquitetura de eventos, poder isolar os consumidores dos produtores
e garantir os mesmos recursos do conjunto acima, mas para os eventos, seria extremamente
interessante a implementação futura de uma Event Mesh.
Problemas isolados
Wordpress e seus plugins
Sempre que dá um problema em algum plugin do Wordpress, não conseguimos saber qual,
onde e porquê. Dependemos do sistema de notificação via envio de email deles funcionar e
estar apontando pro email certo, e que a pessoa esteja na empresa (que não esteja de férias por
exemplo, ou que ainda trabalhe na empresa) e veja o email. Nem sempre o email fala qual dos
wordpress ele está se referindo, e também não temos um controle de como o plugin foi
configurado antes, podemos perder configurações dos mesmos e nesse ponto acaba tendo
retrabalho.
Sei que é quase impossível não existirem mudanças, principalmente aqui que existem muitas
mudanças de escopo não planejadas durante o desenvolvimento do projeto, mas seria
extremamente necessário uma comunicação imediata quando tais inserções e alterações
entrassem no projeto e, tal qual comentei anteriormente, aumentar o prazo do projeto devido
às mudanças. Tudo leva tempo para ser feito, e principalmente nesses casos que o front precisa
mexer em alguma coisa porque o back precisou mudar algo, ou vice-versa, nunca há alteração
de prazo, mesmo que fiquemos alguns dias mexendo no projeto, os prazos se mantém os
mesmos e isso vai erradicando possibilidades de caminhar num ritmo sustentável e com tempo
pra mexer em outras coisas que também são importantes.
Outro ponto que acho extremamente importante e que me desanimou muito no decorrer do
tempo, é que não importa o que eu fizesse, nunca sobrou espaço pra ser Full stack aqui dentro,
mesmo na proposta inicial eu tendo sido contratado para tal.
A filosofia da empresa se tornou ter especialistas, e deixar de lado a ideia de fullstack, porém eu
acredito que isso limita a empresa, porque ter um ou outro fullstack, auxiliaria muito a
comunicação entre os dois times, trocas de conhecimentos mais rápidas (porque mesmo tendo
meetups quinzenais eu acho que não cumpre esse propósito) e em si eu acredito muito que tem
pessoas, como eu, que se sentem muito melhores podendo atuar de ponta a ponta.
Uma outra coisa que eu vejo sendo feito muito pouco é cachear as requisições puderem ser
cacheadas. Uma vez cacheado diminuímos o processamento do servidor e auxiliamos na saúde
do tráfego de dados.
Sei que é necessário uma política boa de cache para não ter problemas, mas vejo que o medo
de fazer algo errado com cache faz com que usemos menos cache do que deveríamos.
Hoje pedimos para que mandem as imagens já otimizadas ou passamos elas no TinyPNG ou no
Squoosh.app, mas todo esse processo é feito de forma manual. Existe uma API do Squoosh.app
que poderíamos utilizar para automatizar nossas aplicações, tal qual existe o Laravel Mix e várias
extensões pro mesmo, ou até mesmo automatizadores de tarefas front-end como Webpack,
Gulp, Bower ou Grunt para isso. Poderíamos usar o Imagemagick, imagemin, avocado e outros
plugins para esses automatizadores que poderíamos usar para otimizar as imagens e gerar
assets otimizados de forma automática.
Uma outra boa prática é cachear o máximo possível os assets que enviamos para o frontend,
para que o usuário nunca tenha que baixar de novo de forma não intencional, um asset que ele
já baixou antes.
Mas para isso precisamos gerar os assets com uma hash no seu nome, sempre que buildamos a
versão de produção da aplicação, e manter um controle de quandos elas são ou não são
alteradas. Existe uma técnica chamada Fingerprint de Assets que pode resolver esse problema.
Para essa parte eu sugiro um curso da Alura chamado Performance Web I e II.
Todos esses problemas e outros podem ser resolvidos, colocando headers na aplicação e no
servidor, de CSP, Content-Security-Policy, os quais posso estabelecer o que o usuário pode fazer
na aplicação; Impedindo que ele mexa no inspecionar elemento, que execute comandos no
console.log que alterem ou interajam com scripts na página e etc.
Existem também algumas versões dedicadas de alguns pacotes para resolver esse problema
como o ga-lite ou o crazy egg por exemplo.
Também seria interessante usarmos o google AMP (o que nos impossibilita de usar CSS
Modules, mas como estamos migrando para Styled Components não seria um problema).
Seguindo boas práticas o google pode disponibilizar uma espécie de CDN de alta velocidade
para nossa aplicação mobile, o que ajuda muito nesse quesito
Outra coisa que seria interessante seria utilizar alguma tática ou library para definir qual é a
primeira dobra do site e fazer um lazy load das informações da página, retornando apenas o que
está nessa primeira dobra. Existem repositórios no github focados nessa tarefa, a qual se dá o
nome de “optimize above the fold problem”, um exemplo é esse pacote
https://github.com/addyosmani/critical-path-css-tools.
Poderíamos usar sprites para a parte das waves também, mas teríamos de mudar a abordagem
usada pelos designers no momento, recebendo apenas um svg e “andando” dentro dele.
Testes de Infraestrutura
Outro problema é a falta de testes de infra, já que utilizamos várias ferramentas de ”infra as a
code”, como terraform, github actions, docker, docker-compose.yml, jenkins file, dentre outros, e
eles podem mudar a sintaxe de uma versão pra outra e pararem de funcionar por exemplo.
Também não é todo mundo que domina essas ferramentas, e esses testes poderiam agregar
grande valor para que essas pessoas se sintam confortáveis em mexer em um coisas ou outra
quando necessário, mesmo sabendo apenas o básico.
Isso seria a base da pirâmide de testes de infra, porém tem outras coisas que seriam importantes
de serem testadas (os níveis mais acima da pirâmide), como por exemplo o quanto conseguimos
garantir que as partes de um sistema distribuído estão devidamente conectadas; Se os
containers estão subindo nas portas e redes certas, se estão na vpn, se disponibilizam x serviço,
se estão funcionando sem erros; Se estão sendo orquestrados de forma correta, se há
escalabilidade de contêineres; Se conseguimos fazer a rastreabilidade de erros nos demais
containeres, se conseguimos saber a vida útil dos mesmos; Se conseguimos interceptar o fluxo
que vem pra cada instância (circuit breaker), se conseguimos subir novos containers na rede e
fazer com que eles ingressam no pool de serviços sem que tenhamos de fazer isso
manualmente, e etc.
Para fazer isso, ferramentas como o Inspec e o Terratest, ou o Serverspec se gostar de Ruby,
podem levar o time a ter grandes resultados, assim como usar a AWS Local Stack para simular o
ambiente no provider na sua máquina pode vir a calhar bastante.
Últimas palavras
De toda forma eu agradeço muito todo o apoio e consideração que tiveram por mim todo esse
tempo e gostaria de desejar um bom futuro aqui dentro, que suas aspirações dêem certo e que
eu ainda escute falar muito bem da Playkids por aí.
Queria que soubessem que esse documento não é para apontar o dedo pra ninguém, ou causar
um mal estar em ninguém, eu só queria deixar sugestões para se tornar um ambiente melhor pra
todo mundo que eu trabalhei junto e para que as coisas que eu tanto acreditei aqui dentro e que
ainda acredito dêem certo.