El Jueves, 7 de Enero de 2010, Robert Klemme escribi

> I'd personally prefer to use the DRb approach because then you can
> actually send typed messages, i.e. whatever information you need.  Also,
> it was fun to play around with those small test programs. ;-)  And you
> can have the reader run on any machine in the network.

Hi Robert, I'd like to thank you the help you gave me in this and other 
threads. Finally I've decided to use posix message queue [*] under Ruby.

The reason is that it allows safely multiple processes or threads using the 
same mqueue to write message (atomic strings) and also having multiple 
processes reading from the same mqueue which means load-balancing out of the 
box :)

The queue size is configurable and the writer/reader can write/read in the 
mqueue in a blocking or non blocking way.

Also, mqueues allow setting a priority to the messages so those messages with 
higher priority are fetched first when reading the mqueue.

Posix message queues are just 20-40% slower than pipes in my benchmarks (but 
pipes are no multiprocess/thread safe).


I would like to share a working example:


---- posix_mq_reader.rb ------------------------------
require "posix_mq"

# Parameters:
# - queue name (must start by "/")
# - flags:
#   - IO::RDONLY   =>  Just to read from the queue
#   - IO::CREAT    =>  Create if it doesn't exist
MQ = POSIX_MQ.new "/my_mq", IO::RDONLY | IO::CREAT

loop do
  # Blocking waiting:
  msg = MQ.receive.first # It returns an array [message, priority]
  puts "messsage received:  #{msg}"
end
------------------------------------------------------


---- posix_mq_writer.rb ------------------------------
require "posix_mq"

# Open with these options:
# - IO::WRONLY   =>  Just to write into the queue.
# - IO::CREAT    =>  Create if it doesn't exist.
# - IO::NONBLOCK =>  Don't block when writting (instead raise Errno::EAGAIN)
MQ = POSIX_MQ.new("/my_mq", IO::WRONLY | IO::CREAT | IO::NONBLOCK)

def send(msg)
  begin
    MQ << msg
  rescue Errno::EAGAIN
    puts "Errno::EAGAIN received, the queue is full!"
  end
end
------------------------------------------------------


Now the reader and writer can be open multiple times sharing the same mqueue 
:)


I also tested your suggested solution with DRb with is really nice, but I 
don't need all the features DRb provides (I just need to pass a simple string 
to other process(es) from multiple workers).


Again thanks a lot to all the people who contributed in this thread, I've 
learnt a lot.

Best regards.



[*] http://bogomips.org/ruby_posix_mq/README.html

-- 
Iki Baz Castillo <ibc / aliax.net>