Archive for February, 2009

Arquitetura “pull” ou “push”: qual escala mais?

Wednesday, February 25th, 2009

Apesar do que possa parecer, esse post não é sobre git. :)

Conversando com o Peleteiro esses dias ele me deu uma idéia interessante. Ia ser o máximo se houvesse um post automático no meu Twitter toda vez que eu ganhasse um achievement no Xbox! Os achievements são como se fossem medalhas: na medida que você vai jogando os jogos e passando de fase ou conquistando coisas, você vai ganhando mais pontos e mais medalhas. Resumindo, é totalmente inútil mas bem legal.

Como nos últimos tempos andei fazendo uma porção de robôs de Twitter para fazer uma porção de coisas, na mesma hora pensei em fazer mais um deles, que ficaria dando requests na API do Xbox Live até que aparecesse um novo achievement e então ele faria o post.

Na mesma hora me bateu a mesma sensação de ineficiência que tive quando fiz os outros robôs. Pra fazer essas coisas eu tenho que ficar fazendo polling no serviço de “n” em “n” minutos para saber das atualizações… Apesar de ser eficiente nao é lá muito eficaz.

Vou fazer uma brincadeira para mostrar o tamanho do problema. Somando só os robôs que fiz para a Globo.com, eu faço diariamente cerca de 72.000 requests para o Twitter (cerca de 25 robôs x 2 requests por minuto x 60 minutos x 24 horas). Ok, nem todo mundo faz robôs de Twitter, eu sei, mas vamos supor que uma pessoa em cada 100.000 faz robôs que nem eu. Isso significaria que só eu e mais uma pessoa fazemos isso no Brasil inteiro (o que não deve ser verdade, mas vamos continuar assim fazendo a conta por baixo). Então considerando que a população mundial é de quase 7 bilhões de pessoas, temos cerca de 70.000 pessoas fazendo o mesmo em todo o mundo. Sendo assim, pela minha conta de padaria o Twitter recebe algo em torno de 5,04 bilhões de requisições por dia, 210 milhões de requisições por hora, quase 60.000 requisições por segundo (só de robôs)!!!

Ok, o número deve ser bem diferente disso. O fato é que com certeza é muito alto.

Eu faço polling no Twitter para buscar por usuários que falaram uma determinada palavra (usando o RSS da busca do Twitter) e então adicioná-los. Funciona assim: quando uma pessoa escreve alguma coisa que eu estou procurando, eu adiciono ela como amigo(a). Apesar dessa quantidade imensa de buscas e requests, um robô adiciona apenas na faixa de 25 usuários por dia. Se houvesse alguma forma de saber que algum usuário escreveu alguma palavra que eu busco, nesse meu cenário só seria necessário fazer algo em torno de 625 requests por dia (menos de 1% da quantidade que eu faço).

O que eu estou propondo aqui não é nada novo. Além dos mecanismos tradicionais de polling (fazer “pull” de arquivos de tempos em tempos), estes tipos de serviços deveriam disponibilizar um mecanismo para o servidor avisar o cliente que alguma informação que ele deseja está disponível (”push”).

Depois da apresentação “Beyond REST? Building data services with XMPP” que rolou na OSCON 2008, o XMPP entrou na moda como uma possível solução para esse problema. Nessa arquitetura, os clientes se “inscrevem” em um serviço de mensagens instantâneas e mantém uma conexão aberta com o servidor para que, quando determinada informação estiver disponível, ela seja enviada ao cliente ao invés dele ter que ficar fazendo “polling”. Isso reduz consideravelmente a carga de requests recebida pela aplicação, mas é mais difícil de escalar para uma quantidade muito grande de usuários.

Uma solução que surgiu na nossa conversa foi um “pingback ao contrário”. Seria algo como o webhook do Github. Quando o usuário fizer um GET em um recurso, ele poderia mandar um header com uma URL, e quando houvesse alguma atualização do recurso o servidor poderia fazer um GET para esta URL com o objetivo de informar ao cliente que há informações novas disponíveis. Essa solução escala mais do que a primeira, mas tem um lado negativo: não funciona se o cliente não tiver um IP real disponível. No meu caso, por exemplo, que tenho robôs rodando no meu desktop da Globo.com (que não tem IP real), não seria possível usar esse tipo de serviço.

Também dá pra fazer algumas soluções mais criativas usando coisas que a princípio parecem esquisitas mas podem fazer sentido. Por exemplo, um servidor de e-mail como o Postfix poderia fazer esse trabalho com o pé nas costas. Quando o cliente acessasse um recurso, ele poderia informar em um header um e-mail para ser notificado quando houvesse atualização. É uma solução bem fácil de escalar e de fácil implementação – tanto pelo lado do cliente quanto do servidor – apesar de não ser muito comum.

Pelo que eu andei lendo o pessoal do Twitter já pensou nesse problema e para resolvê-lo criaram o Firehose, que é uma solução baseada em XMPP. Como eu falei, o problema não termina por aí – eles terão vários problemas novos para escalar XMPP para uma grande quantidade de usuários.

Enfim, esse problema é bem interessante… Na próxima oportunidade que tiver vou tentar fazer uma prova de conceito de todas essas opções para ver no que dá.

E para aqueles que ainda não entenderam, talvez fique um pouco mais claro agora: escalabilidade é muito mais uma questão de arquitetura de software e infra-estrutura do que de linguagens e frameworks.

Apresentando: simple-db-migrate

Monday, February 16th, 2009

Desde o fim do ano passado tenho me divertido um bocado desenvolvendo em Python e Django.

Apesar de ter alguns detalhes esquisitos (especialmente na implementação de OO), Python é uma linguagem sensacional e muito produtiva! O Django também é ótimo e não deixa nada a desejar para o Rails, porém, as comparações são inevitáveis. Uma das coisas que mais senti falta desenvolvendo com Python/Django foram as migrations do Rails. Na verdade, pra quem está acostumado as migrations também fazem falta em Java, PHP e basicamente em qualquer projeto que os bancos de dados são constantemente modificados e complicados demais para serem gerenciados manualmente, independente da linguagem.

Foi por isso que decidi começar o projeto simple-db-migrate. Inicialmente o objetivo era criar algo parecido com as migrations do Rails para o Django, mas agora o objetivo é (além disso) criar migrations para o que quer que seja.

Para isso ser possível as migrations usam DDL ao invés de uma DSL em Python:

Arquivo: 20090215224601_criar_tabela_pessoas.migration

SQL_UP = """
create table pessoas (
    id int(11) not null auto_increment,
    ... etc. ...
);
"""
SQL_DOWN = """
drop table pessoas;
"""

Na verdade, como as migrations são nada mais do que duas Strings Python (SQL_UP e SQL_DOWN), é possível executar qualquer código Python nas migrations que gerem SQL. No futuro isso irá me ajudar a implementar alguma coisa que use os models do Django para criar a DDL automaticamente.

O fato das migrations serem em DDL faz com que eu possa escrever migrations para qualquer tipo de projeto, independente da linguagem e mesmo que no futuro as migrations também possam ser feitas usando uma DSL Python.

Para ver o simple-db-migrate funcionando, depois de instalá-lo (instruções no site), basta ir para o diretório onde estão as migrations e executar:

db-migrate

Se você não quer ter o trabalho de escrever as suas migrations, no diretório “example” tem uma porção delas prontas. Além das migrations é necessário criar um arquivo “simple-db-migrate.conf” com as configurações do banco de dados:

HOST = "localhost"
USERNAME = "root"
PASSWORD = ""
DATABASE = "migration_example"

O arquivo pode ter outros nomes e não necessariamente você precisa estar no diretório das migrations, basta passar essas configurações para o db-migrate pela linha de comando:

db-migrate --dir=migrations_dir --config=path/to/file.conf

Ou output é algo assim:

$ db-migrate --dir=example --config=example/sdbm.conf
 
Starting DB migration...
- Current version is: 20090211120000
- Destination version is: 20090212120000
 
Starting migration up!
 
===== executing 20090211120001_add_user_age.migration (up) =====
===== executing 20090211120002_add_user_mother_age.migration (up) =====
===== executing 20090211120003_create_table_chimps.migration (up) =====
===== executing 20090212120000_create_table_aleatory.migration (up) =====
 
Done.

E por último, já que eu ainda não tenho muita documentação disponível ainda, para ver todas as opções possíveis da linha de comando basta digitar:

db-migrate --help

O simple-db-migrate ainda está em fase embrionária (na verdade comecei na semana passada), mas já está entrando em uso essa semana em dois projetos na Globo.com, ou seja, possivelmente ele vai evoluir bem rápido. Apesar de ainda ser bem simples, tudo que eu mostrei aqui já funciona.

Agora há pouco criei uma versão inicial da página do projeto no Github pages com algumas instruções para instalação e uso (bem simples mesmo, ainda pretendo melhorar bastante). O código fonte está disponível no meu Github e os tickets podem ser acompanhados no Lighthouse.

Plano de cargos e salários…

Sunday, February 15th, 2009

Me incomoda muito o fato de que desenvolvedores precisam virar gerentes ou coordenadores para ganhar mais.

<história>
Era uma vez um desenvolvedor muito bom e muito eficiente. Ao longo da sua carreira ele foi aprimorando suas habilidades e técnicas e se tornou um super desenvolvedor com um conhecimento técnico absurdo, uma vasta experiência em arquiteturas de software e poliglota em linguagens de programação. Nesse momento ele repara que já é um desenvolvedor sênior ++ na empresa que ele trabalha e por isso não tem como ganhar mais do que ele já ganha a não ser que ele vire gerente. Então, querendo ganhar mais, o excelente técnico que programava e resolvia problemas técnicos com eficiência é obrigado a virar um gerente, porque a empresa não dá para ele outra forma de evoluir financeiramente. O detalhe é que ele não tem nenhuma habilidade para gerir pessoas ou projetos, além de que ele odeia fazer isso. O que ele gostava mesmo era de programar, mas ele não teve escolha. Resumindo: a empresa trocou um excelente técnico por um péssimo gerente e ainda está pagando mais por isso!
<história/>

Já repararam como esse padrão se repete nas empresas brasileiras?

Se você nunca parou pra pensar nisso, pense agora: é muito difícil um programador ganhar mais do que um gerente e por sua vez é muito difícil um gerente ganhar mais que um diretor. A lógica do mercado é a velha lógica do plano de cargos e salários: quanto maior for o seu nível hierárquico, mais você ganha.

O problema é que isso não faz sentido. O argumento preferido das pessoas normalmente é que “os gerentes ganham mais porque tem mais responsabilidades”. Eu discordo totalmente. Por exemplo, um amigo me contou ontem que um funcionário da empresa onde ele trabalhava tirou do ar o sistema de transações financeiras de uma grande empresa, causando com isso algumas centenas de milhares de dólares de prejuizo em poucos minutos. Neste caso, um erro de um desenvolvedor provocou uma catástrofe maior do que 10 anos de erros de uma dezena de gerentes juntos. E então, quem é que tem mais responsabilidade nas mãos?

Outra coisa que me incomoda nos planos de cargos e salários são aquelas regras do tipo “gerentes ganham na faixa de R$ X a R$ Y“: se o cara ganha menos que X não pode ser gerente e se ganhar aumento para mais que Y tem que ser promovido a diretor. Isso também não faz sentido. Em todas as empresas que eu trabalhei conheci gerentes excepcionais e gerentes absurdamente idiotas. Por incrível que pareça os excepcionais com toda sua genialidade sempre ganhavam (e ganham) o mesmo que os idiotas, por causa do maldito plano de cargos e salários. Isso pra mim soa como gado: independente das suas características individuais, uma cabeça de gado custa o mesmo que outra.

Eu trabalho e já trabalhei com vários desenvolvedores de valor altissimo. Não falo isso pelo que eles ganham ou ganhavam, mas sim porque em várias situações eles criaram soluções que melhoraram ou mudaram completamente (para melhor) a forma que as pessoas trabalhavam. Algumas dessas coisas foram tão geniais que eu diria que o valor foi inestimável. Eu também já tirei meus coelhos da cartola e sei que eles foram de grande valor para as empresas que eu trabalhei.

Não deveriam ser esses tipos de coisas que determinam o quanto as pessoas devem ganhar?

Em empresas de software, onde é comum encontrar esse tipo de pessoas, deveria ser normal ter desenvolvedores altamente especializados com remunerações maiores que as de gerentes ou diretores, mas isso é tão improvável que eu diria que é praticamente impossível – pelo menos no Brasil. Já em empresas como Google, Yahoo e cia., isso é possível e normal. Na Globo.com temos alguns casos desse tipo, mas são excessões. Isso está em fase embrionária e é muito muito muito longe do que deveria ser.

Naquela história que eu contei no início não consigo pensar em um motivo sequer para a empresa não manter o funcionário como desenvolvedor e dar o aumento que ele merece. Esqueça o plano de cargos e salários e veja como faz sentido: isso seria muito melhor para a empresa – porque o funcionário iria agregar muito mais valor sendo desenvolvedor e iria ajudá-la a lucrar muito mais – e seria melhor para o desenvolvedor – porque ele iria fazer o que gosta, o que é mais experiente e o que estudou sua vida toda para fazer.

Até quando as empresas vão continuar colocando as pessoas certas nos lugares errados?

2009: ano novo, vida nova

Wednesday, February 4th, 2009

O ano novo é sempre um momento de reflexão e mudanças na vida de muita gente. Comigo não foi diferente. :)

Em 2008, por conta do forte movimento para adoção de Scrum aqui na Globo.com, meu blog acabou virando quase que totalmente sobre metodologias ágeis e afins. Por um lado foi muito bom porque durante esse ano pude explorar vários aspectos dessas metodologias e entender profundamente vários motivos e princípios por trás de várias coisas. Por outro lado, acabei falando muito menos do que gostaria sobre minhas raizes… Minha maior especialidade e o que me dá mais prazer é explorar coisas novas, escrever código e desenvolver software. Em 2009 pretendo falar muito mais sobre isso do que qualquer outra coisa.

A segunda mudança é que estou em novos desafios na Globo.com (e por isso ando postando pouco). Depois de dois anos, muitas vitórias e conquistas, no fim de dezembro deixei minha antiga equipe de WebMedia para atuar como evangelista e líder de desenvolvimento de software na Globo.com.

O desafio dessa nova equipe é grande: impregnar a empresa inteira com práticas de desenvolvimento ágil e qualidade de software. Não estamos montando um dos famosos “escritórios de arquitetura” e nem definindo padrões para as equipes trabalharem, mas sim vamos liderar, dar apoio e estimular inovações em desenvolvimento de software, implantar técnicas de desenvolvimento ágil e boas práticas de desenvolvimento e arquitetura de software. Ok, vamos ajudar com processos também, eu assumo – afinal ninguém é de ferro. Para isso tudo vamos fazer vários treinamentos, workshops, vamos trabalhar infiltrados nos times fazendo mentoring com todos os desenvolvedores e sujando a mão de graxa; dentre outras coisas. Traduzindo: diversão garantida e muita história pra contar por um bom tempo!

Já estamos fazendo muitas coisas legais e já começo a ver alguns resultados animadores. Aos poucos vou contando as iniciativas e as novidades!