Alex Rivera | Logout

Python ZeroMQ PUSH/PULL -- Lost Messages?

Asked 2011-07-15T02:47:07.023
9

I am trying to use python with zeroMQ in PUSH / PULL mode, sending messages of size 4[MB] every few seconds.

For some reason, while it looks like all the messages are sent, ONLY SOME of them appear to have been received by the server. What am I missing here?

Here's the code for the client -- client.py

import zmq
import struct

# define a string of size 4[MB] 
msgToSend = struct.pack('i', 45) * 1000 * 1000 

context = zmq.Context()
socket = context.socket(zmq.PUSH)
socket.connect("tcp://127.0.0.1:5000")

# print the message size in bytes
print len(msgToSend)

socket.send(msgToSend)

print "Sent message"

And here is the code for the server -- server.py

import zmq
import struct

context = zmq.Context()
socket = context.socket(zmq.PULL)
socket.bind("tcp://127.0.0.1:5000")

while True:
    # receive the message
    msg = socket.recv()

    print "Message Size is: {0} [MB]".format( len(msg) / (1000 * 1000) )

What am I missing? How do I guarantee that messages are always sent and not lost?

In case it matters, I am using Ubuntu 10.04 32bit, Core Duo machine with 2[GB] RAM.

NOTE: I tried the same example using RabbitMQ and everything works well -- no message is lost. I am perplexed as I often hear praises of zeroMQ. Why did it fail where RabbitMQ succeed?

Edit
Report

1 Answer

16

The problem is that when the program exits, the socket gets closed immediately and garbage collected with an effective LINGER of 0 (i.e. it throws any unsent messages away). This is a problem for larger messages because they take longer to send than it takes for the socket to be garbage collected.

You can avoid this by putting a sleep(0.1) just before the program exits (to delay the socket and context being garbage collected).

socket.setsockopt(zmq.LINGER, -1) (which is the default) should avoid this problem, but it doesn't for some reason that I haven't had time to investigate.

answered 2011-07-15T07:59:51.510

Your Answer