posix-mqueue

Minimal wrapper around the POSIX message queue. The POSIX message queue offers:

  • Persistence. Push messages while nothing is listening.
  • Simplicity. Nothing to set up. Built into Linux.
  • IPC. Blazingly fast communication between processes on the same machine.
  • Blocking and non-blocking. Listeners block until a message arrives on the queue. No polling. Sending messages doesn't block.

Add gem 'posix-mqueue' to your favorite Gemfile.

Still WIP. Not stable. Not everything works as promised.

Usage

require 'posix/mqueue'

m = POSIX::Mqueue.new("/whatever")
m.send "hello"
puts m.receive
# => "hello"

fork { POSIX::Mqueue.new("/whatever").send("world") }

# Blocks until the forked process pushes to the queue
m.receive
# => "world"

# Deletes the queue and any messages remaining.
# None in this case. Otherwise the queue will persist till reboot.
m.unlink

# Queue is now full by default Linux settings, see below on how to increase it.
10.times { m.send rand(100).to_s }

# #send will block until something is popped off the queue, but timedsend takes
# timeout arguments (first one is seconds, second is nanoseconds). If you don't
# want to block on send, pass 0 for both:

assert_raises POSIX::Mqueue::QueueFull do
  m.timedsend(0, 0, "I will fail")
end

# Empty the queue again
10.times { m.receive }

# Like timedsend, timedreceive takes timeout arguments and will raise
# POSIX::Mqueue::Queueempty when it would otherwise block
assert_raises POSIX::Mqueue::QueueEmpty do
  m.timedreceive(0, 0)
end

mqueue

Most important information from the manpages, with a little added information about the behavior of posix-mqueue.

/proc interfaces

Linux has some default limits you can easily change.

  1. /proc/sys/fs/mqueue/msg_max. Contains the maximum number of messages in a single queue. Defaults to 10. You should increase that number. #send will eventually throw an exception if the queue is full (instead of blocking). It does not do that right now.
  2. /proc/sys/fs/mqueue/msgsize_max. Maximum size of a single message. Defaults to 8192 bytes. posix-mqueue allows up to 4096 bytes. You'll be able to change this, soon!
  3. /proc/sys/fs/mqueue/queues_max. Maximum number of queues on the system. Defaults to 256. Which is probably enough.

Virtual filesystem

The message queue is created as a virtual file system. That means you can mount it:

# sudo mkdir /dev/queue
# sudo mount -t mqueue none /dev/queue

Add a queue and a few tasks, count the characters (19):

$ irb
> require 'posix/mqueue'
=> true
> m = POSIX::Mqueue.new("/queue")
=> #<POSIX::Mqueue:0xb8c9fe88>
> m.send "narwhal"
=> true
> m.send "walrus"
=> true
> m.send "ponies"
=> true

Inspect the mounted filesystem:

$ ls /dev/queue/
important  mails  queue
$ cat /dev/queue/queue
QSIZE:19         NOTIFY:0     SIGNO:0     NOTIFY_PID:0

Here QSIZE is the bytes of data in the queue. The other flags are about notifications which posix-mqueue does not support currently, read about them in mq_overview(7).