optional parameter to ZMQ send() [ZMQ_SNDMORE] #12

Open
miko opened this Issue Oct 10, 2012 · 5 comments

Comments

Projects
None yet
3 participants

miko commented Oct 10, 2012

Hello, in order to send a multi-part zmq messages, the ZMQ_SNDMORE flag should be set. I understand that in luv send() should be non-blocking, so ZMQ_DONTWAIT is mandatory, but it would be nice to have option for ZMQ_SNDMORE also.
So my proposal is:
socket:send(mesg[, flags])
(to be future-proof in case zmq adds more flags here), with the comment that the flags will be ORed with ZMQ_DONTWAIT (or not, if that is not mandatory in luv), with default value of ZMQ_DONTWAIT.

Contributor

dvv commented Oct 10, 2012

or-ed means integer constants, not string ones, as in #11 is mentioned, right?

miko commented Oct 10, 2012

Yes, even if you give it as a string, it is internally transformed to integer, so this integer can be ORed with (the integer value of) ZMQ_DONTWAIT.

Owner

richardhundt commented Oct 10, 2012

On Oct 10, 2012, at 11:10 AM, miko wrote:

Hello, in order to send a multi-part zmq messages, the ZMQ_SNDMORE flag should be set. I understand that in luv send() should be non-blocking, so ZMQ_DONTWAIT is mandatory, but it would be nice to have option for ZMQ_SNDMORE also.
So my proposal is:
socket:send(mesg[, flags])
(to be future-proof in case zmq adds more flags here), with the comment that the flags will be ORed with ZMQ_DONTWAIT (or not, if that is not mandatory in luv), with default value of ZMQ_DONTWAIT.

I was thinking of handling ZMQ_SNDMORE transparently like so:

socket:send(frame1, …, frameN)

and then

local frame1, …, frameN = socket:recv()

but maybe that's too much abstraction? Perhaps do as you suggest for socket:send and socket:recv and then add socket:get and socket:put which deals with tuples?

What do you guys think?

miko commented Oct 10, 2012

When receiving the multipart message, the original design is to do this in a loop:

more=true
while more do
  msg=socket:receive()
  more=socket:getsockopt('RCVMORE')
end

The nice thing is that if you want to discard the whole message based on its first part, you don't need to read (and create possibly large, useless objects for) remaining parts.

For sending messages, you need to create all the objects (message parts), but you still could prefer to do it sequentially in order to conserve the memory (the objects could be generated in different moments of a state, i.e. while yielding out of a coroutine).

In such case there would be no point to create :get() and :put(), you just would have to call getsockopt() for each part of a read-in message (and SNDMORE would be an option of send() ). This would be parallel to original zeromq examples, so it is already documented like so: http://zguide.zeromq.org/page:all#Multi-part-Messages.

Anyways, I would prefer send(frame1, ..., frameN) than dealing with "alien" :put()/:get().

Contributor

dvv commented Oct 10, 2012

sounds good.
i'd also think of unifying file:write(x1, x2, ...) with socket:send() -- we could use uv_write feature of taking multiple chunks and avoid concats with are slow in lua

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment