Eventos Periódicos e Assíncronos em Ruby

É por coisas como estas que eu cada vez mais gosto de Ruby em detrimento do Perl (ai se o meu chefe vê isto...). Já alguma vez precisaram que um bloco de código executasse periódicamente (de n em n segundos), sem interferir com a execução do programa, e podendo aceder concorrentemente ao estado do mesmo? Eu precisei...
O meu caso era o seguinte: tenho um programa que faz algum crawling demorado na internet. À medida que este executa vai dando informações de debug para o STDERR. No entanto, depois de ver tudo a executar correctamente, quis que, de 30 em 30 segundos, fosse impresso para o STDOUT informações úteis sobre o progresso do crawler (links visitados, profundidade, tamanho da queue, etc). Felizmente estava a programar em Ruby :-) Rapidamente escrevi uma classe do genero:

class PeriodicEvent
def self.every_n_seconds(n)
Thread.new do
while true
before = Time.now
yield
interval = n - (Time.now - before)
sleep(interval) if interval > 0
end
end
end
end
e depois algures no meu código, escrevi simplesmente isto

PeriodicEvent.every_n_seconds(30) do
# do whatever I want with crawler
# print some things to logger
end
Isto é algo com que eu sonho todos os dias em que tenho que escrever Perl... O bloco definido acima executa numa Thread separada (não bloqueia o crawler), e tem acesso a todas as variáveis declaradas no mesmo scope (não tenho que andar a inventar hacks com threads::shared e companhia).

O Ruby tem uma interface para Threads realmente limpa e fácil de usar. Ao contrário do Perl (onde mais uma vez, threads == hack), as threads em Ruby não nos confundem quando vimos de outras implementações "a sério" de threads, como as pthreads.

Categories

1 TrackBacks

Listed below are links to blogs that reference this entry: Eventos Periódicos e Assíncronos em Ruby.

TrackBack URL for this entry: http://perl-hackers.net/cgi-bin/mt/mt-tb.cgi/20

» Run a code block periodically with Ruby from There's no Place Like ::1

Following a personal project I'm doing involving processes running over weeks, I stumbled upon some code that allows you to run a block of code in a separate thread in Ruby, every n seconds. This works great, as expected, and... Read More

3 Comments

Há um pormenor de que te deves lembrar sempre: o Perl é a mais antiga e optou por uma política (boa ou má, depende do ponto de vista) de compatibilidade, o que não lhe permite ter muita flexibilidade nas mudanças. Graças ao Perl é que o Ruby e o Python são o que são hoje, e em especial o Ruby que teve o nosso amigo designer Larry Wall a trabalhar com eles.

Possivelmente devia dizer isto em particular, mas já que aqui estou, e como acho que não firo sensibilidades, acho que é o facto de andarmos sempre a dizer mal das tecnologias que não usamos (e que não gostamos com ou sem razão) que o Open Source não anda para a frente. Tipo, em vez de dizeres mal do Perl, junta-te à comunidade Ruby e ajuda-a a criar o CRAN (ou lá como se chama). Ok, eu sei que o teu caso é mais para me chatear do que outra coisa.

Possivelmente ainda escrevo um post maior sobre este assunto, mas para já fica aqui o meu ponto de vista.

1. não vejo como as threads em perl (e dentro delas o :shared) sejam um hack. podes elaborar?

2. quando as threads em ruby te morderem (e vão morder) verás como são boas.

Rúben Fonseca Author Profile Page said:

1.
- as threads em Perl não concorrem para as variáveis, todas elas vêem uma cópia das mesmas. isto parece-me mais um fork() do que uma thread.. (se calhar até é assim q é implementado lol)
- threads:shared? fixe.. bota escrever :shared à frente de todas as nossas variáveis que queremos partilhar, que bom! ena, deixou de funcionar? pq? ora bolas, não posso partilhar a variável depois de lhe meter dados.. ora bolas nao posso fazer um simples splice num array partilhado.. ora bolas etc etc etc...
- ora bolas o meu interpretador ficou bastante mais lento só pq o compilei com suporte para threads e 99% do meu código nao usa threads :(
- ....

2.
- ao menos as thread em Perl morderam logo da primeira vez que as usei :P
- so far so good, e enquanto não me morderem, continuarei feliz :)

Leave a comment

About this Entry

This page contains a single entry by Rúben Fonseca published on August 29, 2007 1:45 PM.

Bons Hábitos no uso de Hashes was the previous entry in this blog.

Índices e valores em arrays? is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.