[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