[zeromq-dev] Inconsistency in connect/disconnect behaviour for ZMQ_REQ

Mateusz Jemielity m.jemielity at is-wireless.com
Fri Sep 23 13:02:34 CEST 2016


Hello,

 

I'm doing some tests using ZMQ and found the following behavior: for ZMQ_REQ
sockets, you can connect multiple times to the same endpoint, but you can
disconnect only once from it.

It's seems inconsistent to me, since multiple successful connects suggest
that each connection is separate state stored somewhere. A single disconnect
should then clear one of those states, not all of them. On the other hand,
if multiple connects to the same endpoint create just one state, then I'd
rather like to be informed that the second connect won't change anything.
This is what happens when I bind. Binding to the same endpoint twice for
ZMQ_REQ socket returns an error.

I'm aware that multiple connects can be useful in some situations, for
example, for changing load balance to favor one worker. I'm writing a tiny
wrapper that counts connects and disconnects though, and  I think it would
be better to have some option to control this. Either multiple connects
should allow multiple disconnects or second and next connect should fail. It
would be great to have a socket option to switch between those behaviors.

 

Consider the following short code that demonstrates the issue:

$ cat test_connect_bind_1.c 

#include <assert.h>

#include <errno.h>

#include <stddef.h>

#include <zmq.h>

 

static void

connect_test(void)

{

  void * const ctx = zmq_ctx_new();

  assert(NULL != ctx);

  void * const skt = zmq_socket(ctx, ZMQ_REQ);

  assert(NULL != skt);

  static char const * const address = "inproc://foo";

 

  int result = zmq_connect(skt, address);

  assert(0 == result);

  result = zmq_connect(skt, address);

  assert(0 == result);

  result = zmq_connect(skt, address);

  assert(0 == result);

 

  result = zmq_disconnect(skt, address);

  assert(0 == result);

  result = zmq_disconnect(skt, address);

  assert(ENOENT == errno);

  assert(-1 == result);

 

  result = zmq_close(skt);

  assert(0 == result);

  result = zmq_ctx_destroy(ctx);

  assert(0 == result);

}

 

static void

bind_test(void)

{

  void * const ctx = zmq_ctx_new();

  assert(NULL != ctx);

  void * const skt = zmq_socket(ctx, ZMQ_REQ);

  assert(NULL != skt);

  static char const * const address = "inproc://foo";

 

  int result = zmq_bind(skt, address);

  assert(0 == result);

  result = zmq_bind(skt, address);

  assert(EADDRINUSE == errno);

  assert(-1 == result);

 

  result = zmq_unbind(skt, address);

  assert(0 == result);

  result = zmq_unbind(skt, address);

  assert(ENOENT == errno);

  assert(-1 == result);

 

  result = zmq_close(skt);

  assert(0 == result);

  result = zmq_ctx_destroy(ctx);

  assert(0 == result);

}

 

int

main(void)

{

  connect_test();

  bind_test();

  return 0;

}

 

It passes all asserts:

$ gcc -O0 -ggdb -Wall -Wextra -std=c99 -pedantic test_connect_bind_1.c -lzmq

$ ./a.out 

$ echo $?

0

 

Regards,

Mateusz

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.zeromq.org/pipermail/zeromq-dev/attachments/20160923/a363dae9/attachment.htm>


More information about the zeromq-dev mailing list