quarta-feira, 28 de dezembro de 2011

Acelerando os testes no Django

Finalmente achei algo pra escrever sobre programação. Não vai ser um post longo mas é relativamente útil.


Rápido como o Flash!

Em um projeto que estou trabalhando atualmente, rodamos testes pra garantir que tudo roda como deveria (exceto quando você escreve o teste errado, mas ai é outros quinhentos), e tinhamos o problema de que o teste levava 3 minutos e 35 segundos pra rodar


Aham, sei, 0.2 segundos pra rodar o teste ¬¬

Como da pra imaginar, mais de 90% do tempo era gasto criando tabelas, importando fixtures e criando índices (nessa ordem).

O problema de ter testes demorando tanto pra executar é que você fica de saco cheio de ter que esperar o teste rodar pra saber se tudo funcionou certinho e continuar programando, especialmente porque em essência o TDD deve ser escrito antes do código: Você escreve o teste, naturalmente ele não passa, e você escreve a "correção" para o teste.

Ter que fazer isso com uma lag de 3 minutos entre os comandos é um saco ainda mais se o Google Reader já estiver zerado. Então eu dei um jeito de fazer o teste rodar mais rápido.

Edite o seu arquivo settings.py e adicione o seguinte:

if 'na_memoria' in os.environ:
    print '**********************************'
    print 'Vish, rodando as parada na memoria'
    print '**********************************'
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': None
        }
    }

Quando for rodar seus testes execute assim:

$ na_memoria=1 python manage.py test

Isso fará com que todo o banco de dados de teste seja criado na memória, dando uma acelerada bem grande nos testes. Aqui o tempo de execução caiu de 3 minutos pra 11 segundos (10 segundos importando fixture).

Claro que essa solução funciona apenas se seu código for independente de banco de dados (nada -ou quase nada- de SQL na mão).

sábado, 5 de novembro de 2011

Tunel SSH

É assim que o pessoal costuma abrir tuneis SSH no Japão

Mais um post de infra no meu blog de programação, mas tudo bem, que programador nunca precisou de um tunel ssh pra salvar sua vida?

Tunel SSH nada mais é do que abrir uma porta localmente que responda em um serviço remotamente. Isso quer dizer que você pode conectar em seu banco de dados favorito (PostgreSQL, claro) remotamente sem ter que abrir a porta 5432 do seu servidor aos quatro ventos e sair restringindo o acesso via iptables/ufw/ipfw (até você lembrar que seu IP é dinamico e você não ter paciencia pra reconfigura-lo a cada 3 dias).

Pra abrir um tunel SSH é ridiculamente simples, assim como consta no manual, basta executar:

ssh -L 5433:localhost:5432 user@servi.dor

Com isso, o SSH irá se conectar ao servi.dor e abrir a porta 5433 localmente e encaminhar todas as conexões TCP recebidas diretamente para a porta 5432 do localhost.

Isso mesmo, você não está ficando louco (e nem eu), o ssh vai abrir encaminhar o pacotes para a porta 5432 do localhost. O detalhe aqui fica por conta do contexto, "localhost" no caso é a maquina onde você se conectou, e não a sua, ou seja, nesse caso localhost == servi.dor, é um pouco dificil de visualizar num primeiro momento mas se torna natural depois de um tempo.

Só pra deixar claro: o tunel pode se conectar a qualquer serviço remoto localmente (!!). Pode ser o PostgreSQL, MySQL, Apache, MongoDB, RabbitMQ, até mesmo ao próprio SSH, mas você não vai querer uma implosão no seu computador né?

Básicamente é isso, eu tinha pensado em escrever só o comando e deixar o resto pra você se virar e ententer, então acho que já escrevi de mais

Espero que um dia eu consiga escrever sobre programação, queria tanto falar sobre Celery, MongoDB+Django, e outras coisas....

sexta-feira, 28 de outubro de 2011

man screen

Você conhece o comando screen?

Este artigo assume que o leitor possui um cérebro com uma capacidade cognitiva de associação, ao menos, básica

O comando screen pra quem não conhece é uma ferramenta que permite que você crie terminais que sejam persistentes, ou seja, que não sejam encerrados no logout.

Esse tipo de ferramenta é muito útil quando você precisa executar tarefas em uma maquina remotamente (via ssh por exemplo) e essas tarefas levem muito tempo para serem executadas ou simplesmente deixam o terminal travado para sempre. Comandos como dumps de bancos de dados grandes (grandes de verdade, não esse seu ai), importação de bancos de dados, gunicorn [1], ou algum comando customizado que você criou para o seu projeto Django pra processar alguns milhões de registros.

Nesses casos, você certamente já teve problemas com o terminal que morreu e o processo foi junto por ter perdido seu pai, ai você tentou apelar pra comandos em background, nohup e toda sorte de bruxaria que aparentasse resolver seu problema. Ai sua conexão morria e você invocava os antigos espíritos do mal para que protegessem seu processo.

Sem mais prolixidade lhe apresento: screen

Seu funcionamento é absurdamente simples, basta digitar:
screen -S daora
E um novo shell lhe será magicamente aberto, esse novo shell é um pouco diferente do que você tinha anteriormente, aqui, seu mouse é um mero peso de mousepad, não tente usa-lo pra nada que não seja selecionar texto pra copiar/colar.

Antes que você se desespere porque não consegue mais rolar o texto pra cima ou deixar esse terminal ai enquanto vai tomar um suco de café, vamos ao funcionamento da bagaça

O screen, assim como vim e emacs é baseado em comandos para funcionar, os comando mais basico de todos é: C-a d.

Mas você nunca usou vim nem emacs mesmo, hein?! Ta loks…

Vamos la, quando você ler em qualquer documentação sobre comandos na internet e se deparar com um C-a, isso significa que você deve apertar ao mesmo tempo ctrl+a, e se estiver C-a d, então você deve apertar ctrl+a e em seguida d (leia-se: solte o ctrl+a e aperte d).

No screen, o combo C-a faz com que você entre em modo de comando, ou seja, o que você apertar agora não vai ser passado para o shell, mas vai ser executado pelo comando screen, e ao apertar a tecla d, fará com que esse screen seja desatachado (eita) do seu terminal atual, e você retornará para o shell no ponto que estava antes de entrar no screen. Duvida? Aperte seta pra cima.

Legal, mas agora como voltar para o screen que você tinha aberto? Dica: se você apertou pra cima, não de enter

Quando executamos screen -S daora, nós criamos um novo screen com o nome de "daora". Para ver quais são os screens que você possui, digite: screen -ls, isso vai lhe retornar uma listagem com todos os screens atuais e o status deles.

Para reconectar ao screen, basta executar screen -r daora e você verá de volta tudo que tinha na tela antes de apertar C-a d.

Muitas vezes é necessário rolar a tela pra cima devido a stacktrace muito grande, ou simplesmente ser um stacktrace de java trollface, nesse caso, basta você apertar C-a [, colchetes mesmo, eu não errei a tecla.

Essa combinação vai fazer você entrar em um modo de cópia/scroll, aqui agora é possível navegar pelo terminal como se ele fosse um editor de texto read-only, você pode usar as setas ou mesmo Pg Up e Pg Down e navegar pelo histórico do screen. Não sei dizer qual o limite padrão dessa rolagem, mas você pode customizar pelo parametro -h LINHAS quando iniciar o screen.

Você pode ter quantos screens desejar e sempre será possível voltar a qualquer screen apertando C-a d para sair do screen atual e digitando screen -r outronomedescreen.

Também é possível dentro de um único screen você ter algo parecido com "abas", ou seja, varios terminais dentro do mesmo screen, mas isso é assunto pra outro post, vai se acostumando com o básico que outro dia eu falo desse assunto. Se você já é manjado das artes básicas do screen e ta com pressa pra aprender a usar o spell das abas, segue o link que eu usei pra aprender

[1] - Eu sei que o gunicorn pode ser executado em background e provavelmente transformado em um serviço da sua distribuição, mas lembre-se que eu sou um programador e não um analista de infra, então criar pacote deb, rpm ou serviços não é comigo, então deixe essas coisas pra quem sabe fazer e perdoe minha ignorancia.

PlayStation: Se você não entendeu, o sorvete la no topo é porque a fonetica de "screen" é parecida com "ice cream", para os leigos: "sorvete" em inglês

sexta-feira, 14 de outubro de 2011

Sua conexão SSH travou?

Certamente você alguma vez na vida abriu uma conexão ssh pra algum lugar e alguma coisa aconteceu entre você e o servidor e o terminal congelou (ou assim é o que parece).

Várias coisas podem ocasionar esse problema, desde o seu wifi ter desligado até o servidor ter morrido, mas o problema é que você geralmente tem que fechar o terminal (após elogiar a profissão da mãe de alguém), e era exatamente isso que eu fazia, ficava puto e fechava o terminal.

Seus problemas acabaram!!

Saiba você, que, assim como vim, o cliente ssh dos Unix (não sei se é aplicável a putty, não tenho Windows) possui um modo de comando, e é bem simples, basta apertar ~ (til), uma vez em modo de comando, você pode apertar . (ponto) e isso forçará o cliente a encerrar a conexão e você tera seu precioso terminal local de volta (especialmente mais precioso se estiver em um tty real...ctrl+alt+f1, 80 caracteres de largura, essas coisas sabe...)

Além do ponto, existem outros comandos que podem ser executados. Consulte o man 1 ssh na seção de ESCAPE CHARACTERS que você vai ter a lista com todos os comandos que podem ser executados. Pra mim, o segundo comando mais útil é o ^Z (CTRL+Z) que coloca o ssh pra background e te devolve pro shell local