Ola Povo Agora que foi oficialmente lançado eu posso comentar com calma
https://github.com/Weborama/Riak-Light Em Abril eu comecei a trabalhar na Weborama, uma empresa francesa que emprega alguns caras da comunidade como o OvidPerl e o Sukria. Estou na area de Big Data e fazemos uso intenso de Redis e Riak. Apesar de termos varias opções no CPAN, sofremos em termos de performance com o Net::Riak - que é o unico que suporta a API PBC, que é um protocolo binario simples em cima de Protocol Buffers e bem mais "rapido" que a interface REST. Resolvemos criar um cliente bem enxuto, com foco em velocidade e que não implementa todas as features de um projeto como Data::Riak. Para quem não conhece o Riak é um banco de dados "chave / valor" que tem varias features interessantes (ver http://docs.basho.com/riak/1.3.1/ ). Definido que o que era necessario era basicamente um CRUD (get, put, del), comecei a fazer o projeto usando Moo (subset to Moose mas com foco em performance) e o projeto ficou relativamente rapido (basta ver os benchmarks). Porém exista uma feature importante para ser suportada nesse novo cliente: Timeout de IO. Era interessante setar um tempo maximo para cada operação (leitura ou escrita). E ai, comofas/ Resolvi ser pragmatico e procurar algum modulo pronto. Não tem. No maximo eu poderia usar AnyEvent. Inconformado fui ao google e encontrei pelo menos 3 formas 1 Usar Alarm 2 Usar select 3 Usar setsockopt e setar timeout de entrada e saida Alarm eu poderia fazer de duas formas: uma é setar na mão o alarm em cada operação e a outra é usar o modulo Time::Out, assim eu controlo que cada operação não vai demorar mais q x tempos. Win32 nem pensar. Select é mais "elegante". Aqui o conceito é modificado levemente e eu aguardo por x tempo até poder escrever ou ler. Ainda posso bloquear e levar mais tempo porém parece suprir as necessidades. Como em alguns testes usando um sleep dentro do servidor eu ainda conseguia escrever, eu testei a alternativa de usar select apenas para ler. Deve funcionar no Win32. O setsockopt é o mais bizarro. Eu preciso enfiar um C struct timeval com segundo, microssegundo nas propriedades do socket. Funciona como magia negra. A parte ruim é a portabilidade disso sem ter q apelar pra XS (pack/unpack e ainda estou devendo suporte ao NetBSD), a parte boa é que tem quase nada de overhead. Resultado: criei um sistema plugavel para trocar de estratégia de timeout e fazer os testes, assim basta fazer my $client->new( host => 'foo', port => 9999, timeout_provider => 'Riak::Light::Timeout::Select', timeout => 0.5); e pronto. O padrão é não suportar IO Timeout. Por enquanto vcs podem escolher entre 5 estratégias: Riak::Light::Timeout::Alarm Riak::Light::Timeout::Select Riak::Light::Timeout::SelectOnRead Riak::Light::Timeout::SetSockOpt Riak::Light::Timeout::TimeOut Dessa forma eu consegui fazer um benchmark e saber qual tinha mais overhead e qual poderia não funcionar direito. O codigo fonte esta ai e vcs podem criticar a vontade. Este é o primeiro projeto open source da Weborama e esta disponivel no CPAN. Pra vcs terem uma ideia: Timeout de IO é tão bizarro q eu tenho q abandonar a conexão pq não sei quanto "foi" ou "veio", a conexão fica num estado q não é seguro usar sob pena de ler dados corrompidos. O Stan me deu varias dicas sobre essa parte e eu agradeço. De cara eu penso em remover essa parte de socket com timeout para outro projeto no futuro. Analisei varios projetos como Redis, RedisDB e outros para ver como eles faziam e é uma sacola de gatos essa parada. Só depois eu encontrei este módulo: https://metacpan.org/module/CHRMUE/Socket-Class-2.258/Class.pod que podia me ajudar parcialmente. Eu tenho uma issue com alguns sistemas operacionais como NetBSD e Win32 :/ Sugestões são bem vindas. Pac
=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
