zeromq / cppzmq

Header-only C++ binding for libzmq
http://www.zeromq.org
MIT License
1.95k stars 757 forks source link

Should multipart_t documentation be updated to primarily use add to avoid reverse of traditional order? #637

Open chadrockey opened 5 months ago

chadrockey commented 5 months ago

I am a little confused by the multipart_t functions.

In most/many languages, the push operation will usually default to adding the new elements on the end, at least if you google for "what does push do in programming languages".

With the documentation as written, it doesn't work like the native case in other languages such as:

pub.send(first, send more)
pub.send(second, send more)
pub.send(third, none)

You get an order over the wire and out as first, second, third.

With the documentation as written, if you use push and do

zmq::multipart_t m;
m.pushstr(first);
m.pushstr(second);
m.push(int third);

If you unpack these in order, or even iterate, you'll get them REVERSED

for( auto msg : m)
    std::cout << msg.size() << std::endl;

You'll see you get third, then second, then first. The resolution seems to be to call the "add" methods, which are mentioned nearby on the webpage, but not used at all in the example code. Add will append to the end and do the proper FIFO that newbies like me who look at documentation but don't read it would work better with.

Am I correct in my understanding of the API now?

Another issue I'm not sure I expect to see if that the topic comes through if you use subscriber with a multipart_t. Instead of the three parts above, we will get 4, the first of which is the topic. My new intuition is that subscribers are supposed to strip out the topic for you (see the weather update in the ZMQ guide). I guess it's too late to change this or do anything about it, but I would consider it a bug or unexpected behavior.

gummif commented 1 month ago

My recommendation is to use the send_multipart and recv_multipart functions instead. That gives you the ability to store the messages in a container or pass a range of your choosing.

For subscribe sockets you should always get the topic (if publisher sends 3 frames you should receive 3 frames).