zeromq / jeromq-jms

JeroMQ JMS
25 stars 13 forks source link

Creating a subscriber (almost) always takes exactly 5seconds #9

Closed tommie-lie closed 5 years ago

tommie-lie commented 5 years ago

I have source code like this:

TopicConnectionFactory zmqConnectionFactory = new ZmqConnectionFactory();
TopicConnection connection = zmqConnectionFactory.createTopicConnection();
final TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);

final Topic topicA = session.createTopic("jms:topic:topic_A?socket.addr=tcp://localhost:55555");

Instant before = Instant.now();
TopicSubscriber subscriber = session.createSubscriber(topicA);
System.out.println("A: subscribing took " + Duration.between(before, Instant.now()).toMillis() + "ms");

It always prints a duration of a little over 5000ms. I don't lose any messages during those 5 seconds, instead they are buffered and I receive them all at once. But createSubscriber just blocks for 5 seconds.

5000ms, incidentally, is the value of SOCKET_STATUS_TIMEOUT_MILLI_SECOND. Looking at https://github.com/zeromq/jeromq-jms/blob/master/src/main/java/org/zeromq/jms/protocol/AbstractZmqGateway.java#L187, if the timeout is -1, waitTime is set to 5000. The socket status seems to be asynchronous, as usually the first execution of the loop in waitOnStatus always yields PENDING for the status. It then sleeps for waitTime milliseconds which was set to 5000. Normally, the socket becomes RUNNING only a few milliseconds later, so that I'm waiting uselessly for ~4950ms.

Judging from the naming of the constants, what the code should be doing if the timeout was given as -1 is to keep polling the state but cancel the polling after SOCKET_STATUS_TIMEOUT_MILLI_SECOND. Instead, it polls only every SOCKET_STATUS_TIMEOUT_MILLI_SECOND and still waits infinitely long.

I prepared a pull request to fix this issue.