El Jueves, 7 de Enero de 2010, Robert Klemme escribi=F3:

> 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=20
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=
=20
same mqueue to write message (atomic strings) and also having multiple=20
processes reading from the same mqueue which means load-balancing out of th=
e=20
box :)

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

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

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


I would like to share a working example:


=2D--- posix_mq_reader.rb ------------------------------
require "posix_mq"

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

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


=2D--- posix_mq_writer.rb ------------------------------
require "posix_mq"

# Open with these options:
# - IO::WRONLY   =3D>  Just to write into the queue.
# - IO::CREAT    =3D>  Create if it doesn't exist.
# - IO::NONBLOCK =3D>  Don't block when writting (instead raise Errno::EAGA=
IN)
MQ =3D 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
=2D-----------------------------------------------------


Now the reader and writer can be open multiple times sharing the same mqueu=
e=20
:)


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


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

Best regards.



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

=2D-=20
I=F1aki Baz Castillo <ibc / aliax.net>