Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

zmq-cpp: recv() waits for data despite ZMQ_DONTWAIT being set

I'm trying to implement a non-blocking receive method with ZeroMQ using the ZMQ_DONTWAIT flag but recv() behaves like being called without the flag:

    auto start = std::chrono::steady_clock::now();

    auto have_data = sock_->recv(&reply, ZMQ_DONTWAIT);

    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(
                std::chrono::steady_clock::now() - start).count();

    std::cout << duration << " " << have_data;

sock_ is a zmq::socket_t instantiated as REQ socket.

In this case have_data is always true and duration is whatever the REP server takes to reply (0 to several hundreds milliseconds).

Note that I'm talking about the cpp binding of ZeroMQ defined in zmq.hpp where recv() is differently declared than in zmq.h:

inline bool recv (message_t *msg_, int flags_ = 0);

Here recv() returns true if data has been received and false if errno is EAGAIN

Are there any preconditions to ZMQ_DONTWAIT making recv() return immediately?

(I'm using zmq version 4.1.2)

like image 943
frans Avatar asked Sep 29 '15 12:09

frans


1 Answers

Yes. ( ZeroMQ preconditions should be taken into account. )

A minor note: ZeroMQ allows one to setup a setsockopt() with ZMQ_RCVTIMEO == 0 or a performance-wise reasonable value.

The main issue however is hidden inside the REQ/REP behaviour pattern.

If an Application, on REQ "jumps" right into a state [*] and wait there for anything that might have already arrived into the [REQ]-<Rx>-buffer ( which is principally not possible in this use case ) or that might be will arrive, at some later time, but there is a trouble as the REP counterparty has nothing to reply to and must not and will not .send() anything without a prior .recv() a REQ's request.

    ]-<Tx>- - - - - - - - - +                      + - - - - - - - -<Tx>-[
    ]-<Rx>- - - - - - - -+  |                      :  +- - - - - - -<Rx>-[
[REQ]____________________:__|                      :__|__________________[REP]
                         :  |                      :  |
APP.send() ]--->.send()--:->|                      :  |
           ]             |  :\                     :  |
           ]             |  : \____________________:__|>
           ]             |  :                      :  |M
           .             .  .                      .  .M
           ?             ?  ?                      ?  ?
           .             .  .                      .  .M
           ]             |  :                      :  |M_.recv()--->[ APP.recv()
           ]             |  :                      |  :             [ and
           .             .  .                      .  .             [ can 
           ?             ?  ?                      ?  ?             ?
           .             .  .                      .  .             [ 
           ]             |  :                      |  :             [    .send()
           ]             |  :                      |  :             [ after
           ]             |  :                      |  :             [    .recv()
           ]             |  :                      |  :             [ 
           ]             |  :                      |<-:--.send()<---[ APP.send()
           ]             |  :                     /:  |
           ]            <|__:____________________/ :  |
           ]            M|  :                      :  |
           .            M.  .                      .  .
           ?             ?  ?                      ?  ?
           .            M.  .                      .  .
[*]        ]            M|  :                      :  |
APP.recv() ]<---.recv()_M|  :                      :  |
                         :  |                      :  |
like image 81
user3666197 Avatar answered Nov 13 '22 03:11

user3666197