Archive for August, 2007

Dia de Release, Dia de Sorvete

Thursday, August 23rd, 2007

Hoje fizemos um release aqui. Não, você não vai perceber nada novo no GloboVideos a princípio, é um conjunto de funcionalidades que facilita a vida de quem edita, publica e trabalha com nosso acervo de vídeos e integração com outros sites.

Como o processo tem lá suas exigências não ágeis nós colocamos no ar o que produzimos no Sprint anterior. Nosso ‘done’ deste Sprint foi feito há uma semana e terminamos a homologação oficial com um dia de adiantamento.

Para comemorar mais um release sem problemas instituímos a tradição do sorvete global. Nada de almoços burocráticos de horas, nada de reuniões ou discursos, nada de odiosos tapinhas nas costas. Após o daily scrum dezenas de picolés vieram fazer a festa para comemorar mais uma pequena vitória obtida com o esforço de todos.

Fotos abaixo.

1213705187_65f2365b27_o

1213702153_d36936eb0c_o

1213703235_852f82303c_o

1214564432_0e19f6b766_o

Investindo

Thursday, August 23rd, 2007

Ontem estava conversando com um amigo sobre investimentos. Estava comentando que para um determinado projeto eu teria um orçamento pequeno e precisava otimizá-lo, falei sobre a minha idéia para gerar o máximo possível com a grana em mãos e tive um comentário do tipo: “Cara, caia na real. Aliás, faça as pessoas caírem na real. não adianta você tentar fazer este projeto com este orçamento, não vai sair certo! As pessoas têm que investir para ter alguma grana”. Aí eu fiquei pensando no que faz uma pessoa pensar assim. Não se se concordam comigo mas acho que é “síndrome do oprimido“.

Hoje eu coordeno uma equipe com 8 desenvolvedores, entre seniors e estagiários. As decisões que tenho que tomar são 30% técnicas e o restante de gerência, dizem que a técnica tende a ficar em quase zero mas eu prefiro acreditar numa posição de gerente de desenvolvimento que parece mais com meu perfil.

Há uns sete anos atrás eu peguei meu primeiro projeto relativamente grande naquele esquema completamente ineficiente (e muitas vezes ineficaz) de “analista analisa, programador programa…”. Bom, eu era programador e tinha que apenas implementar um design qualquer. O design era uma grande furada, era tão claro isso que eu achava que todos ao redor eram bestas quadradas. Eu tentei avisar de várias maneiras mas não fui ouvido.

A solução foi continuar avisando enquanto fazia meu trabalho. Dentro daquele design…uhm… não-ótimo eu tentei fazer o melhor que consegui, aplicando o que eu estava aprendendo na época sobre boas práticas, muitas vezes indo contra a filosofia do design, apenas me mantendo compatível o suficiente para não ser despedido. O projeto foi relativamente bem sucedido tecnicamente (os prazos e satisfação do cliente eram os típicos de processos burocrátios, próximos de qualidade zero). É geralmente assim que o programador age.

E foi assim quando assumi posições mais importantes, era um “projetista” (incrível como te gente que acredita que esses cargos realmente existem) e a arquitetura era uma porcaria, era um “arquiteto” e a análise era uma grande bola de nada… e eu como qualquer programador que gosta do que faz fiz o melhor que conseguia dentro daquelas limitações. Óbvio que existiram falhas miseráveis mas a grande parte do trabalho foi um sucesso dentro do possível e este modo de agir contagia quem está em volta e mostra por A+B que as coisas podem ser melhores. Eu introduzi técnicas como Test-Driven Development, Refactoring, Domain-Driven Design, SOA, Componentes, Ruby e outras coisas desta maneira. Eu falava para meu gestor “Ora, precisamos de tempo para fazer Refactoring!” e obviamente era ignorado. Daí eu arrumava um tempinho, fazia meus próprios e mostrava com um gráfico de bugs em partes do código que aquilo dava certo. Geralmente era seguido por um “Ok, vamos tentar alocar mais um tempinho nas próximas tarefas…”.

É engraçado, dê para um programador a tarefa de implementar um POS com recursos modernos em um Pentium 100. Ele vai rir da sua cara, depois vai implorar pro mais recursos, depois vai chorar como criança, depois vai te ameaçar e por último vai ameaçar sua família. Mas, quer saber? No final ele vai sentar na cadeira e tentar fazer o melhor que conseguir. Não, ele não vai fazer mágica, se o que você deu para ele é uma tarefa impossível ele vai seguir até te mostrar isso, mas se não for ele vai tentar conseguir fazer o melhor possível com aquele ambiente tosco.

É interessante que o problema listado acima é exatamente este. Eu tenho que rodar um programa em Java multi-threaded para um 486. É difícil? É. Vou conseguir implementar todos os recursos? Não, mas vou conseguir fazer algumas coisas e falar para meu gerente: “se quiser mais eu preciso de mais”. Quer saber? Talvez ele não queira mais, talvez seja o suficiente.

Cruzar os braços não ajuda em nada. Se algo não é possível prove que não é com números e deixe a decisão para quem deve tomar. Se algo não vai ser bom o suficiente com os insumos supridos e você não consegue mais faça o que conseguir e mostre o quanto mais você poderia fazer com mais recursos.

Introduzindo Agilidade num Ambiente

Wednesday, August 15th, 2007

Toda empresa em que eu já tenha trabalhado, atendido como fornecedor ou prestei consultoria até hoje tem o mesmo discurso: esse negócio de [qualquer novidade] é legal mas aqui dentro não funciona. Pode até funcionar nas empresas certinhas, mas aqui nosso negócio é muito específico, nossa tecnologia é muito específica, nossos banheiros são muitos específicos…. Tenho uma notícia para quem pensa assim: não existe empresa certinha. Todo mundo acha que é diferente dos demais.

Ainda bem que no meu trabalho as coisas não são assim. Todo mercado é dinâmico mas o de Internet chega ao ridículo, da noite para o dia todos os paradigmas mudam. Ao mesmo tempo nós somos o braço de Internet de um dos maiores grupos de mídia do mundo e temos que seguir os mesmos critérios de qualidade, agilidade e inovação dos nossos “irmãos” nos canais de TV, Jornais e Rádios.

Quando fui contratado um dos requisitos era exatamente trabalhar o processo de desenvolvimento da empresa. Não somos diferentes de ninguém, temos um processo que foi criado e adaptado por sete anos e está longe de ser perfeito, como em qualquer lugar padrão. Após algum tempo observando como as coisas funcionam começamos a introduzir mudanças.

Somos uma equipe grande (incluindo alguns colegas blogueiros) que tem como trabalho cuidar de diversos sistemas entre sites, ferramentas de edição e produção de conteúdos e utilitários diversos.

Antes da mudança que introduzimos nosso fluxo de trabalho era o mais caótico possível: alguém enviava um e-mail com algo que estava errado ou precisava ser feito. Este e-mail originava uma tarefa num Gantt Chart. Uma das minhas tarefas diárias era correr atrás da equipe com o cronograma na mão perguntando o que estavam fazendo, depois sentar na minha mesa e atualizar o cronograma. Cada desenvolvedor pegava uma tarefa, ocasionalmente dois dividiam uma mais complexa. Ao terminar o desenvolvedor enviava um pacote para a equipe de testes (nenhum teste além do eventual feito pelo desenvolvedor era feito por aqui) que testava e homologava. Eventualmente o pacote voltava e ia para produção.

A primeira providência foi acabar com o cronograma. Nós temos uma licença do Jira, que apesar dos seus problemas funcionais é um dos melhores issue trackers disponíveis. O fluxo mudou: agora o cliente enviava um e-mail, este entrava no Jira e era designado para a pessoa que dava um prazo para a solução.

Dentro os diversos problemas que ainda tínhamos era colocar coisas em produção. Para homologar, agendar para subir em uma janela, acompanhar a janela, etc etc perde-se muito tempo e a cada tarefa concluída o ciclo era repetido. Solução? Só subir software a cada 15 dias. Em vez de mandarmos 5 ou 7 pacotes por todo o processo mandávamos apenas um e desta forma economizamos muito tempo. Eventualmente conseguíamos fazer mais coisas por parar menos com distrações do processo.

O próximo problema era no mundo das prioridades. Antes alguém mandava um e-mail e olhávamos para ele. Se fosse algo muito grave no nosso ponto de vista (ou se o cliente ligasse reclamando) nós colocávamos a alteração no topo da lista, caso contrário ia para quando “tivéssemos tempo” (i.e. nunca). Obviamente o cliente não ficava satisfeito com essa priorização e nós perdíamos muito tempo trabalhando no que era importante para nós sem saber se era importante (ou mesmo útil!) para o cliente ou não.

Solução? Jogo do Planejamento. Temos diversos clientes internos (e alguns milhões de externos) então elegemos o grupo que realmente representa nossos clientes. Em reuniões semanais de uma hora nós passávamos todas as issues abertas (depois da primeira reunião isso foi rápido) e agendamos possíveis subidas para estas. O cliente pode alterar qualquer iteração, menos a que está em execução. Quando o sistema vai para o ar o cliente recebe uma lista com todas as modificações que subiram para testar e mandar o feedback.

Estava melhor mas ainda não era o ideal. Nossos projetos ainda eram planejados em extensos Microsoft Projects que em algumas semanas perdiam sua sincronia com… o mundo real. A visão era de que o esquema de Jira/Jogo do Planejamento/Release de 15 dias funcionava bem para a manutenção mas não para projetos.

Então mudamos algumas coisas. Após quatro membros da equipe participarmos do curso de Scrum da Teamware nós resolvemos colocar em prática alguns conceitos, melhorando o processo utilizado para manutenção de maneira que servisse para nossos projetos.

Colocar em prática? Como assim?!? O projeto já possui cronograma definido, equipe definida, o escopo vêm sendo discutido há meses! Por que não esperar uma boa oportunidade, com tudo calmo? Simples: porque ela não vai acontecer. Qualquer empresa que queira se manter competitiva vai estar sempre bolando algo novo e mantendo suas pessoas ocupadas com isso. Oportunidade não se espera, se cria.

Para minimizarmos o risco da adoção nós introduzimos as coisas aos poucos. O foco não era implantar o processo X ou o processo Y mas sim coisas que nos ajudassem. O Scrum é um bom molde, um bom guideline. Vamos tentar implantar o molde, se virmos algo melhor ou ruim no caminho adaptamos. Vamos seguir, devagar quando necessário, mas movendo para frente.

Primeiro precisamos diminuir a importância do Jira em favor de post-its. Issue trackes são ferramentas bem interessantes, com o passar dos releases fizemos os usuários aprenderem a abrir issues no jira e acompanhar o andamento por ele (muito menos telefonemas de ’status report’!). Um dos problemas da ferramenta era presença. Para termos o Jira numa reunião precisamos de um notebook e nem todos poderiam utilizar a ferramenta ao mesmo tempo. Outro problema era a granularidade das tarefas. Outro era que cada um tinha sua lista de issues para resolver então eu passava horas (eu diria quase que 8) todo santo dia priorizando todas as issues abertas para cada desenvolvedor.

Picture 001

Para os desenvolvedores deixar o Jira um pouco de lado está sendo simples. Eles já não atualizavam o status dele mesmo! Eu tinha que encher o saco diariamente. Para os outros interessados no andamento do projeto não, após termos ensinado a todos a utilizar a ferramenta falar para olharem para uma outra não seria muito bem recebido. Além disso, muitos dos nossos clientes estão em outros prédios da empresa e não conseguem olhar nosso quadro. A solução encontrada foi mantêr as user stories no Jira, mas não as tarefas.

As user stories passaram a ser blogs. Quando alguém enfrenta uma dificuldade e resolve o problema ele “bloga” um comentário, mas não chega nem a atualizar o status. O uso passou a ser muito mais documental e menos de visão de status. Quando alguma story atinge o status de ‘done’ eu atualizo o status no Jira. A documentação não é tão util, já temos um wiki com especificações técnicas (segundo princípio de Agile Modeling, geralmente fotos dos whiteboards e descrições de alto nível apenas) e estou louco para me ver livre da obrigação de sincronizar com o issue tracker todo dia.

Um dos problemas é que não tínhamos espaço disponível. O escritório oferece uma boa disposição de mesas em baias de 4 pessoas, mas não há paredes disponíveis para pregarmos cartazes.

Picture 009
(desconte a poluição visual da minha mesa)

A solução imediata foi pregar o cartaz com os post-its num rack de servidores para desenvolvimento que fica no corredor.

DSC00460

Hoje já pegamos um antigo laboratório para nossas reuniões mais importantes, mas ficamos um bom tempo apenas com o rack e ainda o utilizamos. Salas de reunião ou mesmo o laboratório são fechadas e os cartazes lá dentro não estão 100% do tempo visíveis. Seguimos com o planejamento do sprint atual no rack e os outros cartazes e artefatos no laboratório. Antes que alguém pergunte tudo é registrado em câmeras digitais e como já me reportou uma vez o Vinícius sobre suas experiências as fotos nunca foram usadas além de decorar Flickrs e 8Ps.

Então todos os dias nos reunimos em frente ao rack para nosso Daily Scrum, uma reunião rápida diária. Um dos problemas que as pessoas sempre levantam para fazer este pequeno “compartilhamento de status” é a hora. Fazer muito cedo as pessoas podem não chegar, muito tarde não vai ser produtivo… bem, aqui a coisa é bem pior. Nossa equipe não exige a priori nenhuma restrição de horário, trabalhamos com pessoas que criam software e soluções, não com recepcionistas que precisam atender o telefone. Como consenso decidimos que as 11 da manhã todos estaríamos aqui. Temos ainda problemas, alguns dias falta um ou outro mas no geral vamos bem.

DSC00462

A reunião dura quase que exatos quinze minutos, para evitar que as pessoas se dispersem precisamos conversar algumas vezes e explicar que o foco é nos objetivos, não no desenrolar das tarefas. Outro ponto foi esclarecer que a equipe se reporta a ela mesma, não a mim. Eu viajei bastante nas últimas semanas e eles precisaram tocar sozinhos, o que fizeram com maestria.

O projeto já estava com as entregas definidas e renegociar não era uma opção. Infelizmente não conseguimos fazer reuniões de priorização com o cliente mas o responsável pela definição de negócio senta aqui do lado e nossos Sprint Backlogs, a lista de coisas que implementaremos a cada Sprint, já estavam bem definidas, com pouca margem para reagendamento (que foi devidamente utilizada).

Para fazer o pouco de planejamento que restava nós nos trancamos numa sala e estimamos todas as tarefas. Nas primeiras iterações mesmo explicando que um Story Point é dado por relatividade (primeiro você acha o mais simples depois estima os outros usando da métrica do “o quanto mais difícil é fazer X do que fazer aquele mais fácil?”) o time surgiu com valores quase que aleatórios para as tarefas, basicamente marcaram um número muito alto para todos. Nas iterações seguintes as estimativas foram ficando mais reais e hoje todos fazemos piada dos valores originais. Descobri que incluir uma reavaliação das estimativas na reunião de retrospectiva pós-sprint é útil para termos um melhor critério.

Na reunião de planejamento de Sprint nós deveríamos fazer uma versão inicial das listas do que precisamos fazer (tarefas) para atingir o objetivo (user story) de cada item do Sprint Backlog. Com medo de introduzir muita coisa nova eu optei por fazer apenas a lista da primeira Story. No final isso se mostrou irrelevante.

DSC00455

A empresa possui seu fluxo de processo já estabelecido e precisamos fazer nosso processo ser compatível com o das outras equipes, que inclui um grande teste de homologação no final. Antes das mudanças o desenvolvedor não executava teste algum, a equipe de QA era a responsável. Com o tempo percebemos o quanto isso era trabalhoso e propenso à erros. Uma das soluções que buscamos é ter testadores na nossa equipe mas enquanto isso não acontece nós mudamos a forma de pensar.

Lá no início da jornada o Guilherme e eu introduzimos testes unitários com JUnit no build. Demorou um pouco mas fatalmente as pessoas começaram a fazer (e as palestras do Guilherme fizeram com que pessoas de outras equipes começassem a fazer testes unitários por si só!). Quando o Bruno entrou na equipe, antes do projeto, uma das primeiras tarefas que dei para ele foi configurar o CruiseControl para fazer build e executar testes unitários. Mais problemas: não havia um servidor disponível para instalar. Conversa aqui, conversa ali conseguimos espaço num servidor de testes que roda diversas máquinas virtuais de VMWare, instalamos Ubuntu e o dito cujo (hoje usaria o Buildx), pronto. Após o CruiseControl o Bruno tratou de integrar o Fit ao nosso processo para fazermos testes de integração, e rodando com o CruiseControl.

Como ninguém tinha experiência com o Fit, o Bruno trabalhou em par com quem pegava a tarefa de implementar os testes. Com uma semana as pessoas estavam escrevendo Fixtures razoáveis, mesmo os estagiários.

Outro ponto que precisávamos testar era a interface, quase sempre web. Avaliamos o Selenium e mesmo com limitações ele parecia razoável mas não ideal. O Tiago investiu um dia integrando o Selenium no nosso build e trabalhando com test-cases em XSTL e fez o mesmo esquema que o Bruno para passar conhecimento. Agora nosso desenvolvimento só está “pronto” quando o código foi criado, com JUnit, com testes no Fit e com Selenium. O último QA achou apenas um bug em um módulo que alguém esqueceu de testar com caracteres especiais.

No primeiro Sprint eu não fiz reunião de revisão. Foi um erro cometido pela pressa mas imperdoável. No segundo nós fizemos uma reunião extremamente útil, levantamos pontos bons e ruins e colocamos num quadro (cuidado, termos fortes abaixo. ambiente irreverente é assim mesmo):

Picture 029

A maior parte dos pontos ruins (no “nem F$#%endo”) eram interrupções externas que eu preciso trabalhar. Minha viagem (que era um dos pontos ruins) recente fez com que os desenvolvedores respondessem por compromissos meus (outro ponto: reuniões que duram dias inteiros) , além de deixá-los sem proteção de interrupções externas (outro ponto citado) como telefonemas e até suporte a outras equipes integrando com nossos sistemas. Tirei daí que se precisar me ausentar preciso deixar alguém como Scrum Master, ainda que o time perca um membro ativo. Diluir o papel de Scrum Master causa mais prejuízos do que tirar uma pessoa do time de desenvolvedores.

Os pontos positivos incluíram o trabalho em equipe, os mecanismos de teste que ajudaram no desenvolvimento, o QA não ter encontrados bugs, a janela para produção ter sido tranquila e outras coisas que basicamente derivam da nova maneira de trabalhar.

Dos pontos ruins o que me preocupou mais foram os referentes a plataforma tecnológica da aplicação. Fizemos uma mudanças grande na direção de uma arquitetura SOA e como qualquer empresa não temos tempo de treinar todo mundo rapidamente.

O desenvolvimento desta arquitetura foi feita basicamente antes do projeto iniciar. Eu incubi o Guilherme de levantar possíveis soluções para nossos problemas de integração e esboçamos o projeto dos WebServices com tudo que tínhamos de melhor, incluindo REST. O primeiro uso desta infra-estrutura foi num projetinho bem curto que realizamos no início do ano e ela se mostrou muito boa.

O problema foi que neste projeto apenas o arquiteto (o próprio Guilherme) e eu metíamos a mão neste sistema. Quando começamos o projeto maior os conceitos ali dentro precisavam ser espalhados. Na primeira iteração com algumas cabeçadas conseguimos um desempenho bom mas ainda não o suficiente. Também vimos alguns pontos onde a arquitetura estava diminuindo muito a produtividade das entregas e que a introdução dos conceitos de WebServices REST, Hibernate/JPA, caches distribuídos e outras coisas menores precisa ser feita com mais cuidado. Algumas pessoas aprendem rápido e sozinhas, outras não e isso não tem a ver com habilidade técnica e sim com perfil (coisa, aliás, que defendo aqui desde sempre).

A solução que pensamos foi adicionar como tarefa um workshop arquitetural. Eu não queria cometer o mesmo erro e trancar o projeto na mão de um membro do time apenas (ou alguns), então nos reunimos durante a tarde. Na primeira parte da reunião o Guilherme explicou a arquitetura do início, mesmo para quem teoricamente já sabia foi útil.

Picture 019

Para estruturar a coisa eu pedi ao Guilherme quatro visões: a estrutura lógica (componentes), a estrutura física (servidores, bancos de dados, etc.), a de pacotes (como os módulos são divididos) e a de caso de uso (descrição do que acontece numa user story relativamente complexa do início ao fim).

Depois nós realizamos um exercício que aprendi no curso da TeamWare: cada um recebeu um bloco de post-it e uma caneta. Por cinco minutos escrevemos tudo que atrapalha nossa produtividade rapidamente, se alguém não pensasse em nada escrevia “nada” no papel. Depois discutimos cada ponto destes sorteando um de forma aleatória. Da forma escolhida para sortear surgiu o nome interno da técnica: a Dança do Siri (derivado da maneira “curiosa” de obter os papéis pelo Tiago):

Picture 027

Houveram poucos pontos técnicos, a maioria de infra-estrutura. Neste meio surgiram também coisas de processo como o papel dos estagiários no time. Um dos pontos levantados é de que nosso time não é tão homogêneo (e qual é?) e nem todos conseguem trabalhar em todas as partes do sistema. Uma estratégia que definimos foi de fazer pares quando ocorrerem estes casos e se tudo mais falhar partir para outra tarefa. O importante é quebrarmos os feudos de sistemas.

Todas foram discutidas, os pontos cabíveis foram anotados e mantivemos o histórico:

Picture 028

Na reunião para a entrega do primeiro pacote tínhamos um problema: descobrimos um erro no cronograma inicial (criado antes do projeto iniciar e antes de adotarmos o processo novo) que iria atrasar o projeto em oito dias. Começamos a reunião com uma descrição do processo de desenvolvimento para os clientes (aqueles que não participam no dia a dia do produto), revisão dos fatos ocorridos que desencadearam no atraso, o que faríamos para voltar ao rumo e a demonstração das funcionalidades. Para nossa surpresa a resposta foi excelente. Os clientes elogiaram a transparência do desenvolvimento, elogiaram o fato de verem algo em produção tão rapidamente e terminamos tendo que responder a uma pergunta: mas por que não fizemos assim antes?

Nós não implementamos o Scrum por completo (me viu falar em burndown chart aqui?), ainda falta bastante. Também não conseguimos eliminar problemas de prazo, tivemos que trabalhar algumas horas extras no último Sprint e possivelmente neste também. Algumas pessoas não se adaptaram aos novos processos e deixaram a equipe. Mas o importante aqui é que elevamos a qualidade do nosso trabalho consideravelmente -a ponto do cliente perceber- e as pessoas estão felizes em trabalhar desta forma, tanto as de fora quanto as de dentro. Paramos de correr atrás do prórpio rabo resolvendo problemas aleatórios diários e estamos trazendo resultados.

Engraçado que outro dia alguém falou comigo no corredor “Poxa, tô sabendo que vocês estão indo muito bem no projeto, heim? Perguntei pra Fulana -uma cliente- e ela disse: ‘É, eles estão gerenciando na linha dura desta vez, estilo sargentão’”.

Será?
Picture 023

Novamente Blogando do Aeroporto…

Wednesday, August 8th, 2007

Claro que o ano mais conturbado da aviação brasileira tinha que ser o ano com mais movimentações aéreas da minha vida…

Bem, estou no Galeão novamente, desta vez voando para Curitiba para voar para Campo Grande para -ufa!- voar para Cuiabá onde se realiza o ENECOMP - Encontro Nacional de Estudantes de Computação. Vou apresentar a palestra sobre Web 2.0, provavelmente é a última sessão desta apresentação.

Possivelmente é a minha última viagem a trabalho este ano. Eu estou inscrito para palestrar no JustJava com o Paulo Silveira mas dadas as já tradicionais mudanças de agenda acho muito difícil que seja possível. Bem, vamos ver.

Arquitetura na Mundo.Net

Sunday, August 5th, 2007

Deve estar nas bancas esta semana a edição atual da Mundo .Net. Esta é a primeira edição com minha participação na coluna sobre arquitetura de sistemas. Existe um estereótipo generalizado de que o Mundo .Net (sem trocadilhos) é muito pouco preocupado com arquitetura de sistemas, consumindo sem pensar as ferramentas que a Microsoft disponibiliza.

Apesar do exagero desta afirmação há de se convir que a maioria dos projetos em .Net usa ‘arquitetura de caixinha’, mas a diferença real para a comunidade Java, por exemplo, é que Java possui muitas arquiteturas de caixinhas para se escolher. Minha idéia para a coluna é focar em temas sobre arquitetura de software que podem ser utilizados nos dois mundos, que são parecidos em muitos aspectos.

Nesta edição o foco é Domain-Driven Design. Eu já falei sobre este tema em uma edição passada da Mundo Java mas desta vez o foco não é nos padrões e sim na modelagem de domínio, com exemplos.