domingo, maio 24, 2015

Testando ZeroMQ - PUSH PULL Clean Shutdown

Estou testando o ZeroMQ (ØMQ) esses dias para incorporar no DeadlySerious (meu projeto de "flow based programming" para processar dados em massa).

A ideia do projeto é só incorporar coisas conforme a necessidade. No caso, estou precisando da algo melhor para paralelizar workers. Seguindo a sugestão do Mereghost, dei uma olhanda no ZeroMQ a fiquei agradevelmente impressionado.

Ao invés de um sistema "faz tudo" de mensageria, encontrei uma biblioteca que se propõe a ser apenas um socket on steroids para facilitar a comunicação inter-processos (e inter-threads). Para o que eu precisava, é perfeito (e rápido que dá medo)!

O maior problema é que precisava de algo que avisasse os workers que o trabalho acabou, mas que não os matasse no meio do processamento. Procurei aqui e ali, mas não achei um modelo que servisse. Mãos à massa e comecei a experimentar coisas, cheguei ao resultado aí embaixo.

A coisa toda ainda precisa de mais testes e acho que a ideia também carece de um certo amadurecimento, mas achei que ficou legal, e ainda por cima, funciona! :D

Esse é o cara que vai receber as mensagens. Ele verifica se a mensagem recebida é uma string "EOF", indicando que o sender já enviou tudo. Se sim, ele pára e avisa o sender que já terminou (usando outro canal). 



Esse é o cara que envia as mensagens. Depois de mandar tudo ele envia uma string "EOF" para cada worker que disse que trabalharia com ele. Como não sabe quem é quem, ele manda um "EOF" e espera alguém responder, quando recebe a resposta ele desmarca esse worker da lista e manda outro "EOF". Assim continua até a lista de workers estar vazia.



Funciona bastante bem, a coisa só não é melhor porque o ZeroMQ manda um bolo da mensagens de cada vez, então, se por algum motivo um dos workers está mais lento que o resto, ele empaca todo mundo até terminar sua cota de mensagens.

Pelo que testei, quanto maior a mensagem, menor esse problema pois o "bolo" que ele manda contém menos mensagens. Mas, convenhamos, esse não é um grande problema.

O ponto mais grave é que se um worker morrer (ou for interrompido), as mensagens que estavam com ele vão pras cucuias.

Acredito que tem como contornar essas coisas, mas por enquanto, ainda não achei jeito :)

terça-feira, maio 12, 2015

Acentos em expressões regulares (Ruby)

Já tentou fazer expressões regulares para dar match em letras acentuadas?

Desagradável...

É comum chegar em algo do tipo:


/[\wáéíóúâêôç...]+/

Mas não se desespere, pequeno gafanhoto. Existe um meio MUITO mais fácil! \o/


/[[:word:]]+/

Não é tão elegante quanto um simples "\w" (que não pega caracteres acentuados), mas é muito mais curto ^_^


Testa aí no IRB, e depois procura por POSIX bracket expressions na documentação do Regex do Ruby, tem mais coisas úteis lá (gosto muito do [[:upper:]]).