sábado, setembro 26, 2015

Ruby 3.0 an Pipes

I just watched the awesome talk of Yukihiro "Matz" (bellow) about the future of Ruby.
There are lots of things to learn from there, please watch.

He talks about SSS (Second System Syndrome - when you try to rewrite software from scratch) and how to avoid the problems of doing it. In summary: "don't". ^_^

If you are going to do a big rewrite do it piece by piece and keep compatibility. That's what he and the Ruby team are going to do for Ruby 3.0.

"No promises", he said, but he gave some general directions for Ruby next steps:

  1. Better interaction man ->machine and back. Actually, better errors (smart errors?) and a sort of static type checking, but not the way we are use to it. He called it "soft type checking", and it resembles more an static code analyser than a language feature :)
  2. Performance. They're trying JIT compilation alternatives,
  3. Concurrency (or should I call "parallelism") ^_^

Part 3 is by far the most interesting. The plan is to remove GIL (Global Interpreter Lock) in a compatible way.

How? Basically 3 steps:

  1. Introduce a better concurrency model than threads (I couldn't agree more).
  2. Give warnings on using threads directly.
  3. Remove GIL (and threads).

He's experimenting on some concurrent models like actors and... wow... PIPES! I just gave a talk in RubyConf Brasil about using Ruby and pipes (good old linux pipes) as a good concurrent model :P

A little toy language called Streem was created to test the concept. And by the time of this writing (sep/2015), Matz is pretty active on it.

I wonder if he had some contact with the work of J. Paul Morrison. As far as I know, Paul is working with this kind of thing, Flow Based Programming, for a couple of decades. His book is really comprehensive on the concept.

I really hope we go that way, my little experience with some of the FBP concepts were amazing. I found it easier and a less error prone approach to concurrency than all other alternatives I tried.



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:]]).

terça-feira, agosto 13, 2013

Ruby method parameters

Encontrei essa ontem: desde a versão 1.9.2-180 existe uma introspecção que retorna quais são os parâmetros de um método.

Confuso? Vai um pouco de código, então:

Ele retorna um array com arrays de 2 elementos, o primeiro symbol é o tipo e o segundo o nome do parâmetro:

  • :req - parâmetro obrigatório
  • :rest - parâmetros variáveis (usando "*" splat)
  • :key - parâmetro nomeado (novo no Ruby 2.0)

sábado, agosto 10, 2013

VIM - "Power of g" + "normal" (massacrando logs)

Essa página aqui me deu a idéia de mostrar uma das coisas que mais gosto no VIM: massacrar logs (e outros arquivos maiores do que minha preguiça permite trabalhar manualmente).

Aqui nesse site aqui tem alguns exemplos de logs legais para brincar: http://www.monitorware.com/en/logsamples. Eu peguei os do PostFix (e-mail) para usar de exemplo.

Copiar todas as linhas com "reject:" para o final do arquivo

:g/reject:/t$

":g" executa comandos em todas as linhas em que a expressão regular der match. O comando "t" copia a linha para um certo endereço. "$" é o endereço para "fim do arquivo".

Se você quiser mover a linha ao invés de copiá-la, troque o "t" por "m".

Copiar todas as linhas com "reject:" para o registrador "a" (para colar onde quiser depois com "ap)

qaq (isso limpa o registrador "a") 
:g/reject:/yA ("y" copia a linha e "A" adiciona ao registrador "a")
ou
:g/reject:/normal "Ayy

Tudo o que vier a seguir do comando "normal" é tratado como instruções do VIM. Ou seja, no exemplo acima "Ayy adiciona a linha no registrador "a" da mesma maneira que você faria na edição normal do vi. "normal" é o comando mais cabeludamente ninja do VIM, pois permite que vocẽ execute macros nas linhas que deram match!.

Aí sim!!!!

Copiar as linhas com "Domain not found" para o final e ficar apenas com o endereço de destino

:g/Domain not found/t$ | s/.*to=<// | s/>.*//

Dá para separar comandos com "|" (pipe). No caso acima, dupliquei para o fim do arquivo e já removi começo e fim de linha que não interessavam. Quando as operações são mais complicadas, o pipe é indispensável ;)

É isso! Eu gosto de pensar no VIM não é um editor de textos, mas como um editor de código com uma linguagem de programação interativa (e suscinta) embutida :D

quinta-feira, junho 13, 2013

Sobrevivendo ao Arch Linux - Atualizando Repositórios do PACMAN

Depois de alguns anos feliz e contente usando o Ubuntu, resolvi me aventurar no Arch Linux (mérito de convencimento do Marcello (vulgo "Cabello") e Marcel (vulgo "Barba"), seus vagabundos!)

**AVISO AOS TRANSEUNTES INCAUTOS**

O Arch Linux não é para os desavisados, a premissa dele é que você precisa entender o sistema para usá-lo. O que significa um bocado de leitura e pesquisa na internet. Use ele se quiser acelerar seu aprendizado, não para ter resultados rápidos e instantâneos sem esforço.

Dado o aviso, vamos ao que interessa: Pequenas dicas para tornar a vida mais fácil.

Atualizando Repositórios

Você tem sua boa e velha lista de repositórios do Arch Linux, mas quando vai instalar algum programa usando o "pacman" ou o "yaourt", percebe que alguns estão lentos, ou pior, alguns pacotes não são encontrados. O que fazer?

  > sudo reflector -l 10 --sort rate --save /etc/pacman.d/mirrorlist
  > sudo pacman -Syy

O reflector é um pacote que você pode instalar via o próprio pacman (ou yaourt):

Rode esse comando uma vez a cada mês que você vai estar sempre bem.

terça-feira, junho 04, 2013

Do the simplest thing that could possibly work

Ontem na empresa surgiu uma excelente discussão sobre o ponto.

Pelo que andei fuçando, existe um grande debate (até hoje) sobre o que significa "Simplest". IMHO:

"Simplest" ≠ "Easiest" ≠ "Quickest"

Essa frase aqui do Ward Cunningham é boa para ilustrar:

We choose simple solutions first so that we can maintain focus on the customer's problem. Simple means easy to reason about. Easy serves as a synonym for simple so long as we remember that it is the thinking that should be easy. -- WardCunningham

(ênfases minhas)

Em termos de arquitetura, minha tradução para "mais simples" se resume a pensar em 4 aspectos:

  • Metáforas (mais fácil de explicar)
  • Simetria (mesma coisa o tempo todo = menos coisas para entender)
  • Componentes pequenos (menor = mais fácil de entender)
  • Protocolos (não preciso entender o "como")