[zeromq-dev] 3.x zmq_msg_t change proposal

Chuck Remes cremes.devlist at mac.com
Thu Oct 27 19:58:51 CEST 2011


While thinking through a few scenarios with DEALER/ROUTER (and XREQ/XREP) in 0mq 3.0, it occurred to me that it doesn't make a lot of sense for us to test the *socket* to see if a message part is a label or not. The zmq_msg_t structure already has this information.

I propose we add a new function that explicitly tests the message and returns true/false/1/0.

// Returns 0 when +msg+ is not a rcvlabel message.
// Returns 1 when +msg+ is a rcvlabel message.
int zmq_msg_rcvlable(zmq_msg_t *msg);

This property belong to the message struct and *not* to the socket.

I think it was added this way because we test the socket to see if a message part is one in a series of messages.

e.g. rc = zmq_getsockopt(socket, ZMQ_RCVMORE, &answer, &answersize);

It felt natural to add the label test to zmq_getsockopt() but I don't think it is correct.

And looking at ZMQ_RCVMORE and how it is used, I'm not convinced this should be a property of the socket either.

I looked back through all of the message threads from the past 1+ years where RCVMORE was discussed (it was introduced around April 2010). I could not see any reason given for why it had to be a socket property.

So, I also propose we add another message function similar to the proposal above for labels.

e.g. int zmq_msg_rcvmore(zmq_msg_t *msg);

Looking forward, there may be reasons to add more flags to the message structure. Creating a new function for *every possible* flag would result in a pretty messy API in my opinion. Therefore, I propose we make this a generic call.

e.g. int zmq_msg_flagmatch(zmq_msg_t *msg, unsigned long flags);

It let's us write the usual code in a more logical manner. The multipart receive from the 3.0 man page becomes clearer IMO.

int more;
do {
    zmq_msg_t part;
    assert (zmq_msg_init (&part) == 0);
    assert (zmq_recvmsg (socket, &part, 0) != -1);
    more = zmq_msg_flagmatch(&part, ZMQ_RCVMORE);
    zmq_msg_close (&part); 
} while (more);

Receiving a REQ/XREQ/DEALER message also becomes far simpler when dividing up the message parts into "envelope" and "body."

int more, label;
zmq_msg_t *part;
do {
    malloc (sizeof(zmq_msg_t);
    assert (zmq_msg_init (part) == 0);
    assert (zmq_recvmsg (socket, part, 0) != -1);

    if (label = zmq_msg_flagmatch(part, ZMQ_RCVLABEL))
      fprintf (stderr, "label part");
    else
      fprintf (stderr, "body part");
    more = label || zmq_msg_flagmatch(part, ZMQ_RCVMORE);
    zmq_msg_close (&part); 
} while (more);

This gives us growth up to 32 flags (I hope we never get to 16!) and allows for multiple tests at the same time.

rc = zmq_msg_flagmatch(some_message, ZMQ_RCVMORE | ZMQ_RCVLABEL | ZMQ_NEWFLAG);

Thoughts on this proposal?

cr




More information about the zeromq-dev mailing list