>>>>> "Stanislaw" == Stanislaw Pusep <[email protected]> writes:
Stanislaw> Thiago, muito obrigado pela excelente resposta!
Stanislaw> Realmente, há muita coisa a ser considerada, todavia, ainda
estou longe de chegar no gargalo do TCP/IP em
Stanislaw> si.
Stanislaw> O que eu percebi é que, infelizmente, não existe nenhum módulo
no CPAN apropriado para gerenciar downloads
Stanislaw> de listas longas de URLs (as minhas listas são de ~500 mil URLs
de arquivos estáticos por sessão). Sim, é
Stanislaw> possível usar LWP e apelar para um fork(), mas aí vi que
consumia RAM/CPU demais, *quando comparado a um
Stanislaw> processo externo*.
Isso depende do processo externo e de como você está forkando. Se você
deixar pra modificar absolutamente o mínimo de dados dentro do processo
forkado, acho bem difícil que um processo completamente novo ocupe menos
memória, já que você se beneficia do copy-on-write.
Stanislaw> E, para mim, como programador Perl, é deveras frustrante
Stanislaw> delegar os downloads ao lftp (http://lftp.yar.ru/
Stanislaw> )... Afinal, o que o lftp tem de tão bom que eu não possa
Stanislaw> fazer em Perl?! ;) Então, implementei o
Stanislaw> AnyEvent::Net::Curl::Queued, que é capaz de gerenciar
Stanislaw> filas bem grandes de downloads, de forma assíncrona. Mas
Stanislaw> será que compensa usá-lo ao invés do lftp? Para isso,
Stanislaw> comecei fazendo benchmarks. Agradeço a todos pelas
Stanislaw> sugestões! Seguem as minhas observações:
Stanislaw> 1. Eden, você está certo, os "filhotes" do LWP tem uma
inicialização muito lenta; e o mais curioso é que
Stanislaw> boa parte da inicialização não está no new() propriamente
dito, mas é feita durante o primeiro request
Stanislaw> (). Então, para ser justo, dividi a minha fila de downloads
em 10 filas separadas, e aloquei um fork()
Stanislaw> para cada uma;
Se você fizer um "warm-up" antes de forkar, talvez tenha mais benefício.
Stanislaw> 4. wget tem o menor overhead de todas as alternativas por ser
ridiculamente simples. Quase não tem
Stanislaw> dependências, por isso a sua inicialização é quase
Stanislaw> que instantânea;
Mas ainda duvido que supere um processo com uma boa implementação
forkante.
Stanislaw> 5. AnyEvent::HTTP é a melhor alternativa para acessar uma
quantidade limitada de URLs *em paralelo*.
Stanislaw> Porém, para listas razoavelmente grandes, gerenciamento via
callbacks e closures é meio tenebroso...
Stanislaw> 6. Reiterando: o *MEU* interesse se restringe a pegar meio
milhão de URLs e baixar de forma mais
Stanislaw> eficiente possível (isso é, o gargalo deve ser minha
bandwidth, não minha CPU/RAM). Nesse caso, pouco
Stanislaw> me importa a possibilidade de fazer parsing de headers,
gerenciar cookies ou processamento de HTML.
Stanislaw> Isso é, quando eu quiser, devo poder habilitar tudo isso;
mas o default deve ser OFF. Portanto, o meu
Stanislaw> "Holy Grail" seria um libwget, que gerencia filas, extrai
links e faz downloads recursivos :)
Mas e se o download precisar de auth, sessão via cookie, proxy, ou
qualquer uma das outras bizarrices do HTTP? Se você coletar casos de uso
típicos, pode implementar um handler otimizado pra cada caso,
introspectar os requisitos do download e fazer um lazy-loading da
implementação correta, isso tudo antes de forkar.
--
Eden Cardim
Software Engineer
http://bit.ly/edencardim
http://twitter.com/#!/edenc
+55 73 9986-3963
=begin disclaimer
Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
SaoPaulo-pm mailing list: [email protected]
L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
=end disclaimer