<div dir="ltr"><div style>Ola Povo</div><div style><br></div><div style>Agora que foi oficialmente lançado eu posso comentar com calma</div><div><br></div><a href="https://github.com/Weborama/Riak-Light">https://github.com/Weborama/Riak-Light</a><br>

<div><br></div><div style>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.</div>

<div style><br></div><div style>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 <a href="http://docs.basho.com/riak/1.3.1/">http://docs.basho.com/riak/1.3.1/</a> ).</div>

<div style><br></div><div style>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).</div>

<div style><br></div><div style>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/</div>

<div style><br></div><div style>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</div><div style><br></div><div style>

1 Usar Alarm</div><div style>2 Usar select</div><div style>3 Usar setsockopt e setar timeout de entrada e saida</div><div style><br></div><div style>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.</div>

<div style><br></div><div style>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.</div>

<div style><br></div><div style>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.</div>

<div style><br></div><div style>Resultado: criei um sistema plugavel para trocar de estratégia de timeout e fazer os testes, assim basta fazer</div><div style><br></div><div style>my $client->new( host => 'foo', port => 9999, timeout_provider => 'Riak::Light::Timeout::Select', timeout => 0.5);<br>

</div><div style><br></div><div style>e pronto. O padrão é não suportar IO Timeout. Por enquanto vcs podem escolher entre 5 estratégias:</div><div style><br></div><div style>Riak::Light::Timeout::Alarm<br></div><div style>

Riak::Light::Timeout::Select<br></div><div style>Riak::Light::Timeout::SelectOnRead<br></div><div style>Riak::Light::Timeout::SetSockOpt<br></div><div style>Riak::Light::Timeout::TimeOut<br></div><div style><br></div><div style>

Dessa forma eu consegui fazer um benchmark e saber qual tinha mais overhead e qual poderia não funcionar direito.</div><div style><br></div><div style>O codigo fonte esta ai e vcs podem criticar a vontade. Este é o primeiro projeto open source da Weborama e esta disponivel no CPAN.</div>

<div style><br></div><div style>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.</div>

<div style><br></div><div style>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.</div>

<div style><br></div><div style>Só depois eu encontrei este módulo:</div><div style><br></div><div style><a href="https://metacpan.org/module/CHRMUE/Socket-Class-2.258/Class.pod">https://metacpan.org/module/CHRMUE/Socket-Class-2.258/Class.pod</a><br>

</div><div style><br></div><div style>que podia me ajudar parcialmente. Eu tenho uma issue com alguns sistemas operacionais como NetBSD e Win32 :/</div><div style><br></div><div style>Sugestões são bem vindas.</div><div style>

<br></div><div style>Pac</div></div>