Search code examples
javazeromqjzmq

jzmq seems to ignore HWM on XREP


I expected the threads in this program work in lock step. However, the sender sends ~60000 messages before waiting for receiver to catch up. What have I misunderstood about HWM?

If I don't start the receiver thread, then the sender blocks when trying to send the second message.

public static void main(String[] args) throws Exception {
    new Thread() {
        @Override
        public void run() {
            ZMQ.Context context = ZMQ.context(1);
            ZMQ.Socket socket = context.socket(ZMQ.XREP);
            socket.setHWM(1);
            socket.bind("tcp://127.0.0.1:8080");
            while (true) {
                try {
                    socket.recv(0);
                    byte[] msg = socket.recv(0);
                    System.out.println("Received: " + new String(msg, "UTF-8"));
                    Thread.sleep(1000);
                } catch (Exception ex) {
                    Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }.start();

    new Thread() {
        @Override
        public void run() {
            ZMQ.Context context = ZMQ.context(1);
            ZMQ.Socket socket = context.socket(ZMQ.XREQ);
            socket.setHWM(1);
            socket.connect("tcp://127.0.0.1:8080");
            Integer i = 1;
            while (true) {
                System.out.println("Sending: " + i);
                socket.send(i.toString().getBytes(), 0);
                i++;
            }
        }
    }.start();
}

Solution

  • At first glance, I thought the same as you and was surprised at the behaviour. But I did some research and I think I found the answer.

    There are other buffers in the system at play here. Setting the high watermark only affects one of them.

    http://www.aosabook.org/en/zeromq.html#fig.zeromq.arch

    Calling send simply pushes to the pipeline and doesn't wait for it to go over the wire. The associated I/O thread reads messages off the pipeline and onto the network. Because you are in such a tight loop sending small messages, it appears that you are filling up the pipeline before the first message is sent.