El Jueves, 7 de Enero de 2010, Robert K.
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.
[*] posix_mq - POSIX message queues for Ruby