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:
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.
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 istoPeriodicEvent.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
Ruby1 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
Tracked on August 31, 2007 8:49 PM
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
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.
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 :)