beanstalkd première approche

Publié par fredix Lun 05 mai 2008 21:27:00 GMT

beanstalkd est un serveur de file d’attente en C développé pour une application Facebook. Il existe un client Ruby mais la documentation est très succincte. Il existe bien un exemple d’usage mais ne répond pas vraiment aux questions, telles que comment obtenir un équivalent des namespaces de manière à ce que plusieurs clients puissent se connecter au serveur tout en écoutant chacun sur leur(s) file(s) et comment savoir que tel message vient de telle file. La documentation du protocole m’a permis d’y répondre.

beanstalk = Beanstalk::Pool.new(['localhost:11300'])
loop do
  job = beanstalk.reserve
  puts job.body # prints "hello" 
  job.delete
end

Le protocole de Beanstalkd parle de tube. Ces tubes correspondent à des files d’attentes. Dans cet exemple de base le client écoute par défaut sur le tube “default”. Si l’on souhaite spécifier le tube à écouter ou bien ajouter un tube il suffit de le préciser :

beanstalk.watch('montube')

Ainsi le client écoutera sur les tubes “default” et “montube”.

beanstalk.ignore('default')

Supprime l’écoute sur le tube “default”. Attention un client doit au moins écouter un tube. L’ignore doit donc être effectué après le watch.

Si l’on souhaite qu’un client puisse écouter sur plusieurs tubes, il y a de fortes chances d’avoir besoin de savoir de quel tube provient un message afin d’effectuer les bons traitements :

job.stats['tube']

Indique de quel tube provient le message reçu. Un exemple complet :

require 'rubygems'
require 'beanstalk-client'
beanstalk = Beanstalk::Pool.new(['127.0.0.1:11300'])
beanstalk.watch('foo')
beanstalk.watch('bar')
beanstalk.ignore('default')
loop do
  job = beanstalk.reserve
  job_hash = job.ybody
  case job.stats['tube']
  when "foo" 
    puts "from foo's tube : #{job_hash[:data]}" 
  when "bar" 
    puts "from bar's tube : #{job_hash[:data]}" 
  end
  job.delete 
end

Depuis un client qui souhaite empiler un message il suffit de préciser quel tube l’on vise, sinon cela sera “default” :

beanstalk.use('foo')

Exemple :

require 'rubygems'
require 'beanstalk-client'
beanstalk = Beanstalk::Pool.new(['127.0.0.1:11300'])
beanstalk.use('foo')
beanstalk.yput(:data => "good")
beanstalk.use('bar')
beanstalk.yput(:data => "bye")

Résultats :

from foo's tube : good
from bar's tube : bye

On a ainsi un usage plus intéressant que les exemples n’utilisant qu’un seul client sur un seul tube. Beanstalkd possède un grand nombre de commandes mais il est dommage qu’il ne fournisse pas pour l’instant d’option de persistance sur le disque. Pour cela sparrow peut faire l’affaire et même s’il est en Ruby, l’usage d’eventmachine peut sans doute lui faire tenir une charge raisonnable. Cependant Beanstalkd possède une communauté très active et des bibliothèques vers 4 langages (pas PHP :P mais cela ne saurait tarder).

Trackbacks

Utilisez le lien ci-dessous pour envoyer un trackback depuis votre site:
http://frederic.logier.org/trackbacks?article_id=beanstalkd-premiere-approche&day=05&month=05&year=2008

Commentaires

laisser un commentaire

Commentaires