Migrando aplicações sem precisar migrar de emprego

Migração. Eis uma palavra que pode assustar vários developers que iniciam suas aventuras no universo devops[^1]. O que realmente isso significa? O que isso traz? E melhor, como executar uma com maestria e baixo risco de colocar tudo a perder?

Cenário

Você tem um software funcionando, porém, recentemente ficou sabendo de novas funcionabilidades que irão totalmente contra ao que você tem atualmente. Nessa hora você pensa: mas como eu irei ajustar todos os dados gerados até agora? Como migrarei contas de usuários, informações privadas e adicionar novas constraints às contas que até agora não precisavam disto? Pois é, amigo. Welcome aboard!

Eu realmente preciso migrar ?

A primeiríssima coisa necessária é: entender o real motivo em seu cenário atual. Isto é: aonde está e para onde irá o sistema com as novas features. Elas realmente confrontam seu system state atual? Algumas vezes, percebemos que a nova feature requer apenas novos dados dos quais nós (developers, devops e curiosos) não teremos como inputar para toda a base atual. Isto resulta em uma tarefa simples: criar um plano de atualização cadastral. Você pode utilizar-se de notificação por e-mail ou/e forçar um update após o login do seu cliente. Sem modificações, sem migrações. YAY!

The rockin’ plan!

Ok, infelizmente não há como executar um update via usuário. A área de operações forneceu uma planilha imensa com os dados e não temos como inserir um a um. Precisaremos migrar dados.

Tudo começou…

… com um plano! Quanto mais refinado, melhor – ou devo dizer: quanto mais refinado, menor a chance de dar tudo errado às 5am ?!

O ponto é: você precisa traçar um plano. É necessário ter começo, meio e fim. Nas primeiras linhas escritas, haverão vários vazios vertendo dúvidas e incertezas. Isto faz parte e você vai preenchendo as lacunas vazias com o passar dos dias. Conforme vai escrevendo seu plano em (uma) folha de papel, indagará uma coisa importante: o que eu farei se alguma coisa der errado?

Você não fará!

Nem sempre você terá um rollback passível de execução – e isto é normal!
Neste momento você sentirá frio, calor, suor e medo, muito medo. Perceberá que é tudo ou nada. É aí que você percebe que você precisa garantir 100% que seu plano funcione.

Automatize tudo que for possível

Parte importante do seu plano é criar tantos scripts quanto possível para realizarem a tarefa para você. O ideal é que durante a migração, você apenas rode uma sequência de comandos que farão todo o trabalho para você. Assim, a chance de esquecer alguma coisa ou fazer alguma coisa não esperada, reduz para menos de 10%.

Rubistas já começam a pensar em Rake Tasks; PHPístas começam a pensar em alguma espécie de recipe – esse é o espírito! 🙂

Defina a ordem de execução

Devo migrar as contas de usuário antes ou depois de definir as categorias dos clientes? Crio a conta deles no ambiente novo ou deveria atualizar a base existente que não contém o plano do usuário?

A ordem de execução é importante e deve ser seguida à risca. Não é possível criar a conta do cliente no novo ambiente o qual requer que todos tenham planos, correto? Logo, a definição do plano por cliente vem como premissa do primeiro item.

Anote em papel todos os steps-to-heaven que você precisará executar. Isto ajudará você a entender melhor da onde está saíndo e para onde chegará após a migração. Neste processo, você encontrará scripts faltantes e até scripts desnecessários.

Practice, Practice, Practice.

Tenho o plano, os scripts e a ordem. O que falta?

Como diria Chad Fowler em seu livro The Passionate Programmer: “você não pode chegar no trabalho para executar algo que nunca tentou antes. Você precisa praticar antes do show acontecer.”

Você precisa praticar. Praticar MUITO!

Seus scripts funcionam individualmente? E dentro do contexto de migração? Se algum falhar ou rodar pela metade, poderei rodá-lo novamente sem prejuízo aos dados já migrados? Atomicidade aqui é vital para uma migração. Você pode e deve considerar o pior cenário: Internet lenta, timeout em conexão com o servidor, etc.

Execute e reexecute os scripts por várias vezes ao longo do período pré-migração. Rode com poucos dados e com muitos dados armazenados. Acompanhe e verifique se está tudo funcionando como deveria. Não deixe de testar também no seu ambiente de staging. Melhor falhar cem vezes agora do que uma vez em produção, não é mesmo?

Momento da migração

Chegou a hora. Você acordou pontualmente às 4hs da madrugada. Parou os serviços que serão afetados e saiu atualizando os softwares de dentro pra fora, ou seja, do mais interno para o mais público dos sistema afetados pela migração. Você visualiza aquela folha com seu plano toda rabiscada e reeditada, já decorada pela sua mente e então começa a migrar.

Caso tenha executado toda a via sacra, provavelmente não terá problemas dos quais não consiga facilmente contornar – isto se houver problemas!

Ambiente migrado, paz interior reestabelecida. Moment of Glory, developer!

Para fechar, acompanhe atentamente o dia de trabalho dos seus usuários para garantir que tudo está como deveria. Se você estiver apoiado com logs ativos (Loggly, Papertrail[^2]), melhor ainda! Há a possibilidade de configurar alertas para você receber em tempo real possíveis traces com problemas enfrentados pelo seus usuários por e-mail ou Campfire[^3]!

Se você não utiliza um recurso assim, recomendo e muito que o faça o quanto antes!

Recipe para migração

Eis um resumão:

  • Verifique a necessidade da migração;
  • Defina um plano de ação;
  • Codifique scripts que farão todo o trabalho por você, faseando-os por atividade dentro da migração;
  • Crie uma ordem de execução dos scripts. Há precedência e pré-requisitos a validar;
  • Pratique muito antes de tentar em produção;
  • Execute em produção, e;
  • Acompanhe o dia dos seus usuários, prestando suporte passivo e ativamente.

[1]: devops é um desenvolvedor de software que assume papel/chapéu de operação do servidor de aplicação.
[2]: Papertrail é um SaaS que salva vidas quando o assunto é logrotate pesquisável, trackeável e alertável via e-mail, Campfire e outros.
[3]: Campfire é um SaaS para chat colaborativo muito simples e útil para se trabalhar em equipe. Uso e recomendo!

Você assinou seu código hoje?

Quem utiliza-se ou já utilizou da annotation @author no cabeçalho de seus códigos levanta a mão !

Annotation @author

Desde que comecei a programar no início do segundo semestre de 2004, eu utilizo desse tal de arroba-aútor. Já vi algumas variantes dela, por exemplo:

Annotation @author Augusta edition

Há ainda aqueles que detalham no cabeçalho sua pog contribuição.
Sinceramente eu nunca fui pesquisar se há uma convenção na utilização deste annotation. O fato é que meu uso com isto é descomplicado:

  • Insiro meu nome em novos arquivos;
  • Adiciono meu nome abaixo do último se eu fiz alguma adição ao arquivo, ou;
  • Não adiciono quando faço pequenas modificações sem acrescentar algo de valor ao então domínio/objetivo/proposta do arquivo.

Mas mesmo assim, sempre colocava no formato **Nome completo **

Porém, não pela primeira vez vejo um developer defendendo o não uso deste annotation. A última vez foi numa discussão – no bom sentido – entre @sergioprado e @lfamorim. Com isto, fui perguntar a eles – e alguns outros mais – a opinião pessoal em relação ao tal annotation. Confira:

Eduardo Guerra@emguerra
Obviamente se o uso de @author nas classes for uma prática da equipe irei segui-la sem problemas, mas se a escolha for minha opto por não colocar. Esse tipo de marcação no meu ponto de vista atrapalha a propriedade coletiva do código por determinar explicitamente os autores da classe. No caso de erros na classe, sempre haverão dedos apontando o autor como culpado, mesmo se não foi ele quem introduziu o problema.

Como toda documentação não-executável, pode deixar de ser atualizado com a evolução de um projeto e muitas vezes o autor original não é mais quem mais contribuiu para a classe no seu estado atual. Adicionalmente, sou a favor de manter o código o mais limpo possível e esse tipo de coisa acaba deixando o código de todas as classes mais verboso.

Cainan Costa@sryche via Jabber
[20:03:08] cainan.costa: não faz sentido, porque o VCS já mostra =P
[20:03:16] cainan.costa: quem é o maluco que fez a parada
[20:03:25] cainan.costa: aí tu usa um git blame
[20:03:33] cainan.costa: e já sabe quem encher de porrada

Lucas Fermando Amorim@lfamorim
Hoje em dia a tag @author é tão obsoleta quanto respeitar um limite de colunas para seu código, mas ainda assim acho elegante e talvez até relevante.

Fica muito mais fácil para aqueles programadores que não usam a IDE XPTO verem o criador de determinado arquivo, método ou função sem ter que recorrer a um programa. É repetitivo você pode alegar, mas eu posso retrucar que a tarefa pode ser automatizada.

Eu aprecio muita essa tag, pois a partir dela posso usando minha humilde IDE identificar o criador de determinados códigos, antecipando os vícios do autor e me adaptando para a leitura. Tudo isso sem abrir a shell e digitar N^C comandos.

N = Familiaridade com o programa X de controle de versão.
C = Commits anteriores.

Christian Benseler@chrisbenseler
Tenho uma visão que o negócio é “mais embaixo”. Antes de tentar assinar um script como seu, o desenvolvedor tem que se preocupar com outros assuntos mais importantes: é um projeto pessoal ou colaborativo? Está prestando serviços a alguém, outra empresa? Qual a política do seu cliente? Qual a versão do script? E qual o tipo de licensa que será adotada?

Só assinar o script não vai fazer a menor diferença se não tiver essas informações. E não vai fazer nenhuma diferença se a comunidade não parar de copiar o script feito por A, retirar os author notes do script e redistribuir o script sem dar esses créditos e/ou sem levar em conta o tipo de licensa adotado.

Carlos Duarte do Nascimento@chesterbr
Antes de mais nada, você se refere a qual linguagem? Em Java, @author pode significar tanto uma anotação em si (e aí depende do contexto), tal como:

@author("chester")

public foo(int bar) {

quanto (o que eu imagino que você queira dizer) a anotação feita em um doclet, i.e.:

  /**
   * Um elemento coberto por JavaDoc.
   * @author chester
   */
    public foo(int bar) {
    …

No segundo caso, eu gosto de @author devido à facilidade em lidar com a autoria coletiva: ela permite anotar classes inteiras ou métodos/atributos particulares; você pode colocar múltiplos autores, e o Eclipse pode ser facilmente configurado para adicioná-la automaticamente. No PHP, se me recordo, é possível usar algo equivalente (phpdoc) em cabeçalhos de código, mas não sei se é válido colocar em métodos/atributos, ou se é possível ter múltiplas declarações no mesmo escopo.

Em qualquer caso, vale notar que sistemas de controle de versão como svn e git são mais eficientes para descobrir quem efetivamente contribuiu com uma classe/método do que esse tipo de tag. Além disso, elas não são suficientes para notas de copyright (ou seja, teriam que ser replicadas apropriadamente para o correto licenciamento do código, independente da licença utlizada), o que limita de fato sua utilidade prática.

Sérgio Prado@sergioprado
Há muito tempo atrás, as ferramentas disponíveis aos programadores eram escassas e limitadas.

Já programei em Assembly com um DOS rodando num x86 e monitor CGA de 80 colunas x 25 linhas

Nesta época, ferramentas de controle de versão não eram tão comuns, nem monitores de 21 polegadas. Foi então que surgiram alguns paradigmas. Eram consideradas boas práticas de programação usar no máximo 80 colunas por linha de código (limitação causada pelos monitores da época), e incluir informações no cabeçalho do arquivo como @version, @author, @date, @changes etc.

O problema é que para muitas pessoas estes paradigmas perduram até hoje, por herança, por gosto (ou mazoquismo mesmo). Qualquer ferramenta decente de controle de versão pode te trazer, desde sua criação, todo o histórico de alteração de um arquivo. Além de ser mais seguro e confiável. Se eu usar no código-fonte “@author pica-pau”, grande parte das pessoas não irá perceber, porque ninguem lê o cabeçalho do arquivo. Também não existe garantia de que o nome documentado no código-fonte é realmente o do desenvolvedor. Já com uma ferramenta de controle de versão esta garantia existe.

Eu mesmo usava @author nos cabeçalhos uns tempos atrás, mas parei de usar depois que comecei a criticar alguns paradigmas que tinha. É tudo questão de delegar para ferramentas o que pode ser automatizado e buscar novas soluções para os mesmos problemas.

Fábio Miranda@fabiolnm
Não uso por pura falta de hábito – nunca trabalhei em um projeto onde essa prática fosse adotada.
Mas acho interessante, não só o autor, como o email / github tb.

Pode ocorrer de ser necessário dar manutenção em determinado código cuja compreensão não seja trivial, e a possibilidade de contactar o autor, mesmo que remota, deve ser considerada e viabilizada. Não vejo razão para ser contra.

E pra finalizar, os comentários fundamentados de Hanneli Carolina @hannelita – sobre o uso de @author e muito mais:

Bom, vou dar minha opinião sobre comentários no código antes de qualquer coisa…. Também utilizarei algumas metáforas e exemplos reais.

Eu já trabalhei com códigos de sistemas legados – Mainframes e sistemas bem antigos – , envolvendo C e Assembly. Vou contar uma coisa – quando abríamos um código e víamos infinitas linhas de comentário, já sabíamos que vinha coisa ruim pela frente. Tudo bem para aquele tipo de código sempre achei necessário comentar – Há algumas subrotinas do inferno que precisam de explicação. E o cara que fez isso tem idade pra ser meu pai, já faleceu ou se aposentou. Portanto, códigos assim são “legíveis” graças aos comentários deixados para trás. Já peguei código em Assembly sem comentários. E fiquei quase 10 dias só pra entender por cima o que o programa fazia.

Mas atualmente estamos em uma época onde encontramos linguagens extremamente expressivas, como Ruby e Python. E pra ajudar ainda tem uns framewroks tipo Sinatra, incorporando DSLs. Ou seja, hoje é possível escrever códigos que HUMANOS são capazes de ler. (humanos comuns, quis dizer hehehe). Se você escreve códigos em Ruby que humanos não entendem, então sinto muito, meu amigo, vá ler o Clean Code ou aprender a programar de forma limpa. Aliás, práticas de TDD ou BDD, por exemplo, influenciam e praticamente geram um código limpo e legível dadas as etapas que sugerem na construção da aplicação. Por exemplo, o famoso “Vermelho, verde, refatorar” do TDD – O refatorar ocasiona um cógido extremamente mais compreensivo. Construído tal código sólido e bem estruturado, eu questiono – comentários para que? Eles perdem o sentido. Por exemplo, você se depara com a seguinte expressão em Ruby:

unless valor == 0
    puts "Valor diferente de zero!"
end

Bem expressivo, certo? Pra que um comentário então? Uma das coisas que me irrita um pouco é encontrar códigos assim:

public class Pessoa {
    private String nome; //define o nome da pessoa
    private int idade; // define idade da pessoa
}

Ou pior, bem pior que isso:

public class Pessoa {
    private String a; //define o nome da pessoa
}

Ambos os casos eu considero inapropriados. O primeiro por gerer redundância – é ÓBVIO que o atributo “nome” faz menção ao nome da entidade pessoa! O segundo exemplo nos remete a alguém que não fez uso de bom senso de orientaćão a objetos para definir o nome do atributo. O comentário era necessário porque não houve refatoração e uso de um nom esclarecedor ao campo. De qualquer forma, isso é incorreto no meu ponto de vista.

Então quando usar comentários? Costumo usar comentários quando, por exemplo, utilizei algum recurso pouco conhecido da linguagem. Por exemplo, o uso de Fibers no Ruby – poucas pessoas sabem o que são Fibers; coloquei um comentário no meu código extremamente sucinto explicando o que era e onde achar mais informações. Ou se você utilizar alguma magia-negra no código, embebida por metaprogramação, por exemplo, acho que é bom deixar um comentário sucinto do que aquilo quis dizer. Esse tipo de comentário ajuda programadores juniors a adquirir experiência e ajuda até memso os seniors a captar a idéia geral de um método/bloco que possui lógica complexa.
E há alguns casos que comentários podem ajudar a leitura do código fluir e ficar mais agradável. Pra Java, por exemplo, existe uma API – GAG >= Google Annotations Gallery da qual já fui colaboradora. Essas anotações dão emoćão ao código; de vez em quando acho interessante utilziar algumas delas; tornam o coódigo mais expressivo. Novamente, acho que se deve usar sem abusos =)

Sobre o uso do @author – Aí já acho que é uma cosia meio pessoal. Eu não coloco. Saber que sou colaboradora/commiter do projeto já está bom pra mim. A ligação entre eu e o código fonte vai muito mais além que um @author. Claro, tem o lado bom de se colocar; todos que tiverem o fonte saberão o responsável por aquela ciração, e poderão parabenizá-lo, encontrá-lo no Twitter ou no Facebook e coisas do gênero. Ou poderão xingar sua mãe com vontade. Mas acredito que há outras formas de se descobrir e pedir ajuda sobre algum fonte que não são através do @author.

Bom, essa é minha visão geral da coisa! =D

E aí, é contra ou a favor do @author ?

O poliglotismo do desenvolvimento pseudomoderno

No início, quando “softwares” disponíveis através do browser não passavam de sites pessoais munidos com ingênuos formulários para contato, quem fosse capaz de entender C ou Perl rodando em CGI era rei. Com a evolução de hardware, servidores, linguagens de programação, browsers e etc., aquelas linguagens em CGI ganharam novas utilidades, cada vez agregando mais itens às ferramentas produzidas.

A coisa toda deslanchou quando CRMs e ERPs começaram a ganhar versões web, direcionando-se para um modelo centralizado, eliminando a necessidade daquelas instalações em clientes, controle das versões, módulos e todo aquele inferno toda aquela via sacra que é controlar isto.

Os softwares web evoluíram, mas ainda precisavam do bendito refresh a cada ação. Surge então, a brilhante idéia baseada em uma API Microsoftiana esquecida ao léu, concebida ainda na década de 90, onde na ocasião os desenvolvedores a chamaram de XMLHttpRequest e tinha como objetivo iteração entre Outlook e Internet Explorer, provendo acesso ao Outlook Web Access. Ah sim, isso é conhecido pelos stakeholders como Ajax.

Com o advento desse tal Ajax, as telas baseadas em funcionalidades puderam evoluir para telas baseadas em eventos – o que pode ser conversa para outro post – Com essa utilidade, softwares web-based aumentaram em quantidade astronômica e junto levaram a complexidade às alturas !

Essa tal de complexidade, começou a exigir dos softwares comunicação com outros softwares, iteração com diversos dispositivos: hardware hospedeiro; ferramentas e dispositivos físicos plugados na máquina cliente, ou seja, na máquina que está acessando o software via browser. De frente à toda essa necessidade, no início teimaram em prover tudo isso com sua Linguagem de Programação Preferida e Bala de Prata ™. O resultado ? Perda de desempenho, muito dinheiro gasto com códigos que apenas satisfazem a necessidade da linguagem (i.e. Java, oi ?) e noites sem dormir.

PHP é uma excelente linguagem que muitos programadores PHP ainda não conhecem porém, não insista em controlar a impressora do cliente com a tal linguagem por que você simplesmente tomará na cabeça !

Disso, surgiu, assim digamos, um novo tipo de programador: o poliglota. Isso não quer dizer que entender ahn, COBOL e PHP torne-o passível de ser tachado como tal. Martin Fowler em entrevista à Paulo Silveira na Agile Brazil 2010, afirmou sem titubear que o programador poliglota é aquele que trabalha com mais de uma linguagem de programação em um mesmo software.

Neal Ford, tem uma visão um pouco mais abrangente sobre poliglotismo: ele afirma no livro The ThoughtWorks Anthology que o grande ponto do poliglotismo é aproveitar o que cada linguagem que roda sobre a JVM tem de melhor a oferecer. Ele dá exemplos de Java + Groovy; Java + JRuby e até Java + Jaskell. Isso é sem dúvidas infinitamente melhor do que tentar fazer uma aplicação em PHP e testá-la com Ruby e Cucumber sem qualquer tipo de integração direta =P

Desenvolver desta forma é mais comum do que se pensa ! Os primórdios dos Internet Banking’s foram construídos – e assim continuam – desta forma. Nada de arquitetura SOA! – O banco ABN AMRO tem um artigo sobre SOA publicado no JISTEM-USP – É utilizado Java e PHP com o módulo PHP-Java bridge para tal mágica. Empresas como Facebook, Last.fm, Google, Yahoo! utilizam mais de uma linguagem para uma mesma ferramenta como é anunciado na rede. Isto demanda profissionais com algumas características:

  • Livre de tecnologia. Os fanboys de linguagem de programação ficam a ver navios;
  • Domínio da teoria. Não basta ficar preso às facilidades de uma linguagem X ou Y; Faz-se necessário conhecer o por quê das coisas, pois uma linguagem pode ser mais ou menos easy-to-use do que a outra;
  • Interesse em conhecer novas formas e padrões: não adianta forçar-se a programar com o estilo Java com linguagens como Ruby. Camel case não é o padrão em Ruby;
  • Vontade em conhecer novas linguagens. No livro The Pragmatic Programmer é pelos autores recomendado que você aprenda uma linguagem nova a cada ano, e;
  • Estar apto a mudar tudo quase tudo, sempre!

Diante de tudo isso, qual linguagem “investir”? Eu levo em consideração a minha vontade na linguagem. Não é porque a linguagem Scala não está no topo dos mais procurados que eu não partiria para aprendê-la e usá-la em meus projetos e experimentos pessoais. É questão de afinidade com a linguagem. O mercado? Virá atrás de você de forma natural.

Artigo originalmente postado por mim no até então blog Ready to Sail, hoje, o planet da Vex.