Quinta-feira, 9 de Julho de 2009

Globo Vídeos: Quem viu este vídeo também assistiu

É com muito orgulho que anuncio que acaba de sair para degustação uma nova funcionalidade do Globo Vídeos. Foi uma alteração que durou apenas um dia de desenvolvimento envolvendo o time inteiro e que ficará no ar por um tempo ainda em versão de teste. Trata-se de uma forma de ofertar vídeos baseada nas preferências de nossos usuários. Chamamos a funcionalidade de "Quem viu este vídeo também assistiu".



Como ainda está em versão "beta", para visualizar a alteração é preciso ter o addon Grease Monkey instalado no seu Firefox, e instalar o script que habilita a funcionalidade beta. Depois basta acessar o Globo Vídeos para poder aproveitar a nova facilidade disponível. E se possível, nos dê feedback dizendo o que achou e se encontrou algum problema na utilização. A opinião de vocês é muito importante para que a gente possa melhorar.

Teste de aceitação automático com múltiplas configurações no rails

Dado que uma aplicação possua duas maneiras ou mais de funcionar de acordo com alguns parâmetros de inicialização, como proceder com os testes de aceitação automáticos sem ter que iniciar e parar o servidor entre cada cenário ou grupo de cenários?

A solução simples, mas bem funcional que adotamos, foi ter uma task rake para inicializar vários servidores no ambiente local, cada um com um environment e uma porta diferente. Assim, ao testar uma determinada funcionalidade com determinada configuração basta acessar o servidor naquela porta.

A task rake que poderia até mesmo ser um shell script, ficou mais ou menos como mostrado abaixo. Créditos ao Tiago PacMan, mestre em shell, que fez a linha que finaliza os servidores.


desc 'Inicia servidores para teste de aceitação'
task "server:test" do
system 'RAILS_ENV=test_conf_1 script/server -d -e test -p 3001'
sleep 1
system 'RAILS_ENV=test_conf_2 script/server -d -e test -p 3002'
sleep 1
system 'tail -f log/test.log'
system "ps aux | awk '/3001/{print $2}' | xargs kill -9"
sleep 1
system "ps aux | awk '/3002/{print $2}' | xargs kill -9"
sleep 1
end

Repare que para este caso fizemos uma modificação no environments.rb para unificar os logs de todas os ambientes de teste.

Já no ambiente de integração contínua, onde utilizamos apache com passenger, foi mais simples ainda, bastando definir para diferentes VirtualHosts RailsEnvs diferentes.

Resolvendo o "missing uri map" no mod_jk

Esses dias instalei o Ubuntu 9 em meu desktop e desde então tenho preparado o ambiente de desenvolvimento de diversas aplicações legadas. Uma delas necessita do apache conectando no tomcat pelo mod_jk. Após fazer a instalação de ambos e ter configurado os pontos de montagem do módulo, tudo de acordo com minha instalação antiga, deparei-me no log com o seguinte erro:

jk_translate::mod_jk.c (3038): missing uri map for tiago.motta:/MeuPathAqui

Descobri em uma grande thread de IRC que o problema ocorre quando o apache possui algum VirtualHost configurado, e que para resolver isso basta habilitar a configuração "JkMountCopy On" no VirtualHost correspondente.

Sábado, 6 de Junho de 2009

DynamicStream garantindo compatibilidade com flash 9

Ao implementar o DynamicStream em seu flash, teoricamente pararia de funcionar em clientes com a versão 9, pois algumas das classes e métodos necessários para seu uso só estão disponíveis apartir da versão 10.

Para evitar isso a Adobe disponibilizou um artigo mostrando como integrar o DynamicStream em um player antigo, para que só utilize o recurso novo quando o plugin do cliente estiver na versão 10, garantindo assim a compatibilidade. Este artigo possui até mesmo um exemplo, que embora funcione sem problemas em flash 9, quando integrado em outros projetos não funciona.

O problema é um bug na classe de referência que a Adobe oferece em diversos de seus artigos sobre essa funcionalidade. O erro fica evidente quando utilizamos um flash player debugger de versão 9 sobre o swf gerado, até mesmo os de exemplo da empresa.

verifyError: Error #1053: Illegal override of play2 in DynamicStream.

Esse erro ocorre porque a classe DynamicStream de referência sobrepõe o método play2 de NetStream apenas para anulá-lo. Com isso o plugin fica obrigado a verificar a existência do método play2 em NetStream e acaba dando o erro, pois tal método só está disponível apartir da versão 10.

Removendo esse método da classe DynamicStream de referência, tudo passa a funcionar, pois o acesso aos recursos existentes nas versões maiores ficam restritos ao conteudo dos métodos, que só serão avaliados em tempo de execução.

Não fosse o Bruno FMS me dar a dica do flash player debugger, perderia mais um bom tempo testando diversos artíficios para tentar fazer o código rodar em flash 9.

Terça-feira, 2 de Junho de 2009

Iptable para testar fallback para rtmpt no flash

Para testar se o fallback do seu flash player está funcionando corretamente, e acessando o flash media server pela porta 80 com rtmpt, basta configurar seu iptables para rejeitar ou deletar os pacotes da porta 1935, que é a padrão do FMS:

sudo iptables -A OUTPUT -p tcp --dport 1935 -j REJECT

ou

sudo iptables -A OUTPUT -p tcp --dport 1935 -j DROP

Sem esquecer de ao finalizar seus testes limpar o iptables para continuar seus testes:

sudo iptables -F

Segunda-feira, 11 de Maio de 2009

Padrões de URLs com expressões regulares no Fakeweb

Ao usarmos o Fakeweb aqui onde trabalho encontramos a necessidade de registrar grupos de URLs de acordo com um padrão. Inspirado no Anselmo Alves, colega de minha equipe que corrigiu um bug nesta mesma gem, alterei-a de forma a permitir o registro de URLs utilizando regex.

Com essa alteração, se por exemplo você quiser que todas as chamadas a um determinado host sejam respondidas com uma determinada string, basta registrar como o mostrado abaixo:

FakeWeb.register_uri(:get, /programandosemcafeina\.blogspot\.com/, :string => "Meu blog")

O principal desafio no desenvolvimento dessa nova funcionalidade foi não quebrar compatibilidade com o uso anterior. Dessa forma, os registros de URLs absolutas passaram a ter uma prioridade maior independente da ordem em que forem registradas. Ou seja, os retornos de acordo com as expressões regulares só são executados se a URL absoluta solicitada não estiver registrada. Veja o exemplo abaixo:

FakeWeb.register_uri(:get, "http://programandosemcafeina.blogspot.com/search/label/rails", :string => "Label Rails")
FakeWeb.register_uri(:get, /programandosemcafeina\.blogspot\.com/, :string => "Meu blog")
FakeWeb.register_uri(:get, "http://programandosemcafeina.blogspot.com/search/label/ruby", :string => "Label Ruby")

Net::HTTP.get(URI.parse("http://programandosemcafeina.blogspot.com/search/label/rails"))
=> "Label Rails"

Net::HTTP.get(URI.parse("http://programandosemcafeina.blogspot.com/search/label/ruby"))
=> "Label Ruby"

Net::HTTP.get(URI.parse("http://programandosemcafeina.blogspot.com/search/label/rmagick"))
=> "Meu blog"

Já solicitei ao Chris Kampmeier a integração do meu fork, mas enquanto ela não é feita, você pode utilizar a gem gerada diretamente do meu repositório no Github. Basta intalar da seguinte forma:

gem sources -a http://gems.github.com
sudo gem install timotta-fakeweb

Segunda-feira, 4 de Maio de 2009

Undefined method request_uri com HTTParty

Dica rápida para quem está utilizando HTTParty: Se por um acaso você se deparar com o seguinde erro:

undefined method `request_uri' for #<URI::Generic:0xb03919c>
/mnt/apps/filmes/vendor/gems/httparty-0.3.1/lib/httparty/request.rb:56:in `setup_raw_request'
/mnt/apps/filmes/vendor/gems/httparty-0.3.1/lib/httparty/request.rb:39:in `perform'
/mnt/apps/filmes/vendor/gems/httparty-0.3.1/lib/httparty.rb:153:in `perform_request'
/mnt/apps/filmes/vendor/gems/httparty-0.3.1/lib/httparty.rb:119:in `get'
/mnt/apps/filmes/app/models/Filme.rb:25:in 'com_tags'

Não se desespere, URI:Generic realmente não possui o método request_uri. O problema é na incialização do HTTParty. Se base_uri estiver nulo qualquer requisição utilizando a classe obterá esse erro. Teste você mesmo algo como:

class A
include HTTParty
base_uri nil
format :xml
end

A.get('/search/label/ruby')

Ao corrigir a inicialização de base_uri o erro deixa de acontecer:

class A
include HTTParty
base_uri 'http://programandosemcafeina.blogspot.com'
format :xml
end

A.get('/search/label/ruby')

O problema é passível de ocorrer principalmente se base_uri for configurável de acordo com o ambiente em que a aplicação estiver rodando.