Confira na prática como 12 desenvolvedores, divididos em 4 times, conseguem trabalhar na mesma base de código sem gerar bugs. Será apresentado o case de produção do site globoesporte.com.
Integração entre times e o desafio de desenvolver uma aplicação (v2)
1. Integração entre times e o desafio de
desenvolver uma aplicação
Ciclo de Palestras Infnet
2. 2
Victor
Pantoja
Engenheiro Eletrônico e de Computação pela
UFRJ e mestre em Informática pela PUC-Rio,
possuo mais de 9 anos de experiência
desenvolvendo grandes sites focados no usuário.
Scrum Master da área de aplicações móveis
(before it was cool) de 2007 a 2008.
Atualmente, sou desenvolvedor web sênior no
globoesporte.com.
3. Background
Scrum na globo.com desde julho de 2007
4 Times Ágeis com 3 a 4 dev + 1 Infra + 1 DBA +
SM + 1 PO
Maioria do software em Python / Django
3
6. Cenário 2011
6
- 1 time recém-formado trabalhando no globoesporte.com
- nenhum dos desenvolvedores jamais havia trabalhado no
portal e nem com o framework por trás dele
- código legado construído sobre um framework quando
este ainda estava no início de seu desenvolvimento.
- testes escassos
- não sabíamos o impacto das alterações que fazíamos mas
7. Cenário 2011
7
- SporTV.com foi o primeiro projeto deste time
- ownership do código e do projeto
- começamos a conhecer cada linha de código do
projeto
- definimos padrões de código e de testes
10. Mudanças
10
- novos sites Combate e Eu Atleta (desenvolvidos pelo time
1)
- importantes eventos esportivos com data bem definida,
como as Olimpíadas de Londres 2012 e Copa do Mundo
FIFA 2014
11. Mudanças
11
1 time trabalhando no
globoesporte.com
1 time trabalhando no
SporTV
1 time trabalhando em
Classificação / Tabelas /
Tempo Real
1 time realizando
integrações com o Cartola
FC
13. Mudanças
13
Cada time possuía seus próprios padrões de
código e testes e sua verdade absoluta
Os padrões que impúnhamos não eram
aceitos pelos demais times e sentíamos que
faltava diálogo
19. Diálogo
19
Reuniões periódicas para:
-falar sobre o que cada time está fazendo
-identificar pontos de sobreposição de
trabalho e reuso de código
-discutir novas tecnologias
-melhorar nosso processo de trabalho
20. Segregação do
Código
20
- havia uma quantidade (pequena) de bugs
introduzidos em código alheio
- código legado anterior ao meu time e do
meu próprio time precisava ficar isolado
21. Segregação do
Código
21
Em essência, Django Application é simplesmente um
pacote Python que segue algumas convenções. Essas
convenções são importantes, pois permitem que o
Django detecte suas características e agregue suas
funcionalidades ao projeto.
e: http://henriquebastos.net/desmistificando-o-conceito-de-django-a
22. Segregação do
Código
22
-divisão do globoesporte.com em dezenas
de apps isoladas que falam entre si apenas
por interfaces
-nenhum método de uma app que não
estivesse exposto poderia ser usado
-facilidade no gerenciamento do ciclo de
vida de cada app
28. Como resolver?
29
Perguntar se alguém usa certo trecho de
código se mostrou bastante ineficiente pelo
tamanho do projeto
29. Como resolver?
30
-Ambiente único de integração continua
(CI) para dar mais visibilidade a todos os
testes
-pipeline para testar o branch de cada time
frente ao código de produção
-pipeline para testar o branch de cada time
frente aos demais branches
31. Como resolver?
32
Coordenar releases:
- todo time deve avisar aos demais de sua
intenção de subida
Mostrou-se o método mais eficiente
para reduzir problemas com subidas
para produção
32. - o objetivo é garantir que o código da apps
Django estejam bem isolados
- isolamento de testes através de um
settings no projeto que faz referência
apenas para a app em questão
Isolamento dos
Testes
35. Trouxemos nosso PO para nosso lado
mostrando os benefícios:
E o nosso PO?
- menos bugs em produção
- maior aproveitamento de código = mais
features desenvolvidas em menos tempo
37. 38
- o que funciona hoje provavelmente não
funcionará amanhã
- crie novas formações dos times para
disseminar “boa cultura”
- introduza novos conceitos e práticas para
melhorar a integraçao (enquanto ela
existe…)
Todos os 9 anos na globo.com.
Já fiz muito caso de uso e de testes.
E diagramas enormes no MS Project com tudo direitinho: custos, caminho crítico…
Acho que todos sabem que trabalhamos com Scrum a uns 7 anos.
Éramos 4 times. Agora apenas 3.
Criativamente chamados de esportes1, 2, 3 e 4. Tem gente que chama de alfa, beta… mas não somos criativos a esse ponto.
Mas antes, alguns dados sobre o globoesporte.com para vocês entenderem o tamanho do problema!
Com o passar do tempo e com o amadurecimento e maior integração dos desenvolvedores do nosso time, passamos a ter ownership do projeto. Conhecíamos cada linha de código e sabíamos exatamente para que cada método servia e onde ele era usado. Definimos muitos padrões de escrita de código e também de testes sem consultar os demais times da área de esportes que cuidavam dos demais projetos como o Cartola FC e o Futpedia
Timelapse esportes1
Esse cenário começou a mudar quando surgiu a necessidade de reconstruir o globoesporte.com e atualizar sua linguagem visual e editorial. Diversos novos tipos de conteúdo seriam agregados ao portal. Surgiram sites como o Eu Atleta, o Combate e o redesenho do SporTV. Havia em nossa direção as Olimpíadas de Londres 2012 e do Rio de Janeiro, em 2016. Havia também a primeira Copa do Mundo FIFA de Futebol aqui no Brasil depois de 64 anos.
Era impossível que apenas um time fosse responsável por tudo isso. Passamos a ser 4 times trabalhando juntos no globoesporte.com e no Tempo Real.
Criação de branches por time
O meu time, denominado esportes 1, tinha a missão de guiar o desenvolvimento, uma vez que possuíamos uma imensa bagagem adquirida em quase 3 anos de desenvolvimento do portal. Porém, cada time já estava trabalhando junto havia algum tempo e possuía seus próprios padrões e cultura de testes, autonomia de deployment para os seus ambientes de desenvolvimento e de produção e também seus problemas e suas verdades absolutas
Cada time trabalha em um branch. Um time pode introduzir bug no código de um outro com alguma facilidade… é apenas uma questão de tempo
Precisa ser assim?
Como fazer essa galera remar junta?
A falta de conversa foi declarada a grande vilã e o primeiro problema de integração que atacaríamos.
Decidimos que faríamos reunião periódicas e que a freqüência dependeria da necessidade de se passar conhecimento
No começo, como tudo era novo para todos, optamos pela reunião semanal. Nestas reuniões, falávamos um pouco sobre o que cada time estava fazendo e tentávamos identificar possíveis problemas de integração, como pontos de sobreposição de trabalho tanto a nível de componente quanto de métodos necessários para se construir um certo elemento da página. Se nessa reunião fosse identificado que dois times estavam atuando em elementos parecidos ou que pudessem aproveitar algo já feito do outro, isto deveria ser discutido. Nestas reuniões também discutimos assuntos de nosso interesse: algo que tenhamos pesquisado ou alguma tecnologia que gostaríamos de experimentar.
Pela falta de integração, passamos a introduzir uma quantidade pequena, porém significativa, de bugs no código de outros times. Uma alteração no comportamento de um método podia quebrar um outro em um ponto de código que jamais suspeitaríamos. Havia ainda muito código legado anterior ao meu time e ainda mais código legado escrito por nós mesmos durante nosso amadurecimento.
Decidimos usar a linguagem de programação (Python) e o framework Django a nosso favor e optamos por quebrar o globoesporte.com em dezenas de apps isoladas que falariam entre si apenas por interfaces. Ou seja: nenhum método não exposto poderia ser usado e, se fosse usado, seria por conta e risco do desenvolvedor
Decidimos usar a linguagem de programação (Python) e o framework Django a nosso favor e
optamos por quebrar o globoesporte.com em dezenas de apps isoladas que falariam entre si apenas por interfaces. Ou seja: nenhum método não exposto poderia ser usado e, se fosse usado, seria por conta e risco do desenvolvedor.
Por exemplo, temos uma app chamada globoesporte-core que, como o nome sugere, possui todos os métodos comuns a várias apps. Dessa forma, nossa app “jogo” depende fortemente da app “core”. Porém, essa relação é assimétrica: a app “core” não depende da app “jogo”. Imagine agora outra app chamada “materia”, contendo o código necessário para termos notícias no globoesporte.com. A princípio, esta app não deveria depender de “jogo” mas existe a crônica de um jogo que nada mais é que uma matéria e essa dependência passa a existir. O interessante neste caso é reduzir ao máximo o acoplamento entre elas.
A forma de se fazer isso depende da linguagem de programação e cada uma tem sua implementação. Em Java, por exemplo, isso pode ser feito através de métodos públicos e privados. Em Python, o desenvolvedor pode expor apenas os métodos desejados através do arquivo __init__.py.
Claro que o grau de acoplamento vai depender do objetivo e funcionalidades da sua app.
O ambiente local é a Tomorrow Land, onde tudo funciona como você quer e nada pode dar errado.
Na globo.com, como na maioria das empresas de TI, temos nosso ambiente de desenvolvimento local e os ambientes de testes antes de chegarmos ao ambiente de produção.
Daí, seu código chega em produção e (oh!) não funcionou. Pior, quebrou o código do seu colega do lado que trabalha em outro time e desenvolveu uma funcionalidade que você nem sabia e que estava usando este mesmo trecho de código que você alterou. O que aconteceu neste caso foi a integração tardia do código.
Decerto, a maneira mais rápida de resolver problemas como o descrito no parágrafo anterior é perguntando se alguém usa esse método. Porém, em um projeto grande, como o globoesporte.com, em que dezenas de apps são mantidas e evoluídas por vários times, perguntas desse tipo rapidamente podem se transformar em uma inspeção visual de código a procura de pontos que utilizem esse código.
Os times do globoesporte.com decidiram automatizar esse procedimento de duas formas: ambiente único integração contínua e criação de um ambiente de testes com todo o código mais recente instalado. A primeira forma significa simplesmente que teríamos um CI único e que utilizaríamos o Jenkins para tal. Dessa forma, todos os testes de todos os projetos seriam executados juntos e ficariam sempre visíveis.
A segunda, ambiente único de testes, significa que toda alteração em que houvesse dúvida, ou certeza, de que haveria impactos em outros pontos deveria ser testada frente aos branches de desenvolvimento das demais apps. Isso feito, era preciso também coordenar as subidas para produção. Se um time tem alguma subida planejada, ele deve avisar aos demais. Além disso, se um time estiver pensando em realizar uma subida, deve consultar os demais. Essa integração, por ser mais simples, é feita utilizando nosso bom e velho email corporativo ou, melhor ainda, falando com o colega do lado.
Os times do globoesporte.com decidiram automatizar esse procedimento de duas formas: ambiente único integração contínua e criação de um ambiente de testes com todo o código mais recente instalado.
A primeira forma significa simplesmente que teríamos um CI único e que utilizaríamos o Jenkins para tal. Dessa forma, todos os testes de todos os projetos seriam executados juntos e ficariam sempre visíveis.
A segunda, ambiente único de testes, significa que toda alteração em que houvesse dúvida, ou certeza, de que haveria impactos em outros pontos deveria ser testada frente aos branches de desenvolvimento das demais apps.
Isso feito, era preciso também coordenar as subidas para produção. Se um time tem alguma subida planejada, ele deve avisar aos demais. Além disso, se um time estiver pensando em realizar uma subida, deve consultar os demais. Essa integração, por ser mais simples, é feita utilizando nosso bom e velho email corporativo ou, melhor ainda, falando com o colega do lado.
De nada vale isso se os testes não existirem. Então, escreva testes!!!
Isso feito, era preciso também coordenar as subidas para produção. Se um time tem alguma subida planejada, ele deve avisar aos demais. Além disso, se um time estiver pensando em realizar uma subida, deve consultar os demais. Essa integração, por ser mais simples, é feita utilizando nosso bom e velho email corporativo ou, melhor ainda, falando com o colega do lado.
Após passar todo a apresentação falando sobre integração, esse quarto passo pode parecer contraditório. Porém, antes de buscar resolver problemas de integração é bom ter certeza de que o código de sua app está bem isolado do de outras.
Essa verificação poder ser facilmente feita através da execução isolada de testes funcionais. Como utilizamos Django, a forma que encontramos foi termos um settings para cada app que seria usado nos testes isolados e que conteria apenas as dependências básicas no atributo INSTALLED_APPS.
Adeque-se a novas formações de times e a novos conceitos. A evolução da tecnologia nos mostra diariamente que o que funcionou hoje pode não funcionar tão bem amanhã.
Acredito que nada do que foi dito aqui é novidade. Não reinventamos a roda, apenas aprendemos a trabalhar em conjunto com os demais times através do diálogo constante.
Perguntem por favor! Quem tiver com vergonha, nossos twitters são...