JustinTulloss/zeromq.node

Send from a request endpoint can trigger receive callbacks

Opened this issue · 3 comments

Following on from a question I filed on StackOverflow:
http://stackoverflow.com/questions/39573399/why-are-my-request-and-response-messages-out-of-order

... from my reading of the code, a call to zmq.socket("req").send(...) can lead to a "message" callback being executed. In binding.cc, this seems to be because Socket::Sendv can call socket->NotifyReadReady().

Why does the code work this way? It seems to me to break the expected flow of Node.js, which is that events will only be triggered once the event loop finishes executing the current code. The way this is designed, the execution of the current code suddenly jumps to triggering callbacks and then returns to executing the current code. Why can't it just wait until the event loop is ready to check for responses? This behaviour should at least be separated out into a new send_and_check function or something.

It works the way it does, because of how zmq deals with notifying us about received messages. That can come at unfortunate times (like when checking for socket status during a send). Once notified, it won't notify us again, so we need to act. I've been out of the project for a few months now, so my memory is not 100% fresh, but I think/hope #516 may make the implementation a bit more clean.

I think this is where the behavior got introduced: #531

... from my reading of the code, a call to zmq.socket("req").send(...) can lead to a "message" callback being executed

has anyone ever checked for a send() callback? If there is one, we need to fix that.

In binding.cc, this seems to be because Socket::Sendv can call socket->NotifyReadReady().

that section probably isn't labeled correctly, but the important check is ZMQ_POLLOUT

NotifyReadReady() is identical to NotifySendReady(), namely, calling either one signals I/O

"Once notified, it won't notify us again, so we need to act."

Sounds like zmq should be building up a buffer of received messages ready for the event loop rather than immediately triggering the callback.