zeromq / libzmq

ZeroMQ core engine in C++, implements ZMTP/3.1
https://www.zeromq.org
Mozilla Public License 2.0
9.71k stars 2.35k forks source link

How to distinguish between full high-water mark and authentication(ZAP) failure when meeting EAGAIN from zmq_msg_send ? #4453

Open moyotar opened 1 year ago

moyotar commented 1 year ago

Please use this template for reporting suspected bugs or requests for help.

Issue description

Environment

Minimal test code / Steps to reproduce the issue

  1. use a socket with ZAP relevant options to connect a server without ZAP options,then try to send several messages and will get EAGAIN.
  2. set a small HWM, and try to send messages to get message queue full. We will also get EAGAIN.

What's the actual result? (include assertion message & call stack if applicable)

In Both of the two situation, We will meet EAGAIN from zmq_msg_send.

What's the expected result?

Is there a way to clarify then?

ljluestc commented 5 months ago

#include <zmq.h>
#include <stdio.h>
#include <unistd.h>

int main() {
    void *context = zmq_ctx_new();
    void *socket = zmq_socket(context, ZMQ_REQ);

    // Set HWM to control the maximum number of outstanding messages
    int hwm = 100;
    zmq_setsockopt(socket, ZMQ_SNDHWM, &hwm, sizeof(hwm));

    // Connect to the server
    zmq_connect(socket, "tcp://localhost:5555");

    // Send multiple messages
    for (int i = 0; i < 1000; i++) {
        zmq_msg_t msg;
        zmq_msg_init_size(&msg, 5);
        memcpy(zmq_msg_data(&msg), "hello", 5);

        // Attempt to send the message with non-blocking flag
        int rc = zmq_msg_send(&msg, socket, ZMQ_DONTWAIT);
        if (rc == -1 && zmq_errno() == EAGAIN) {
            // If send operation would block, retry after a short delay
            usleep(10000); // 10 milliseconds
            i--; // Retry sending the same message
        } else if (rc == -1) {
            // Handle other errors
            perror("zmq_msg_send");
            break;
        }

        zmq_msg_close(&msg);
    }

    zmq_close(socket);
    zmq_ctx_destroy(context);

    return 0;
}