1

I'm using NetMQ (Nuget 3.3.2.2) on .NET 4.5 and I have a single fast generator process with a PUSH socket, and a single slow consumer process using a PULL socket. If I send enough messages to hit the sending HWM, the sending process blocks the thread indefinitely.

Some contrived (generator) code which illustrates the problem:

        using (var ctx = NetMQContext.Create())
        using (var pushSocket = ctx.CreatePushSocket())
        {
            pushSocket.Connect("tcp://127.0.0.1:42404");

            var template = GenerateMessageBody(i);
            for (int i = 1; i <= 100000; i++)
            {
                pushSocket.SendMoreFrame("SampleMessage").SendFrame(Messages.SerializeToByteArray(template));

                if (i % 1000 == 0)
                    Console.WriteLine("Sent " + i + " messages");
            }
            Console.WriteLine("All finished");
            Console.ReadKey();
        }

On my configuration, this will usually report it has sent about 5000 or 6000 messages, and will then simply block. If I set the send HWM set to a large value (or 0), then it sends all of the messages as expected.

It looks like it's waiting to receive another command before it tries again, here: (SocketBase.TrySend)

        // Oops, we couldn't send the message. Wait for the next
        // command, process it and try to send the message again.
        // If timeout is reached in the meantime, return EAGAIN.
        while (true)
        {
            ProcessCommands(timeoutMillis, false);

From what I've read in the 0MQ guide, blocking on a full PUSH sockeet is the correct behaviour (and is what I want it to do), however I would expect it to recover once the consumer has cleared its queue.

Short of using some sort of TrySend pattern and dealing with the block myself, is there some option I can set or some other facility I can use to have the PUSH socket attempt to resend blocked messages periodically?

McSti
  • 51
  • 3
  • 1
    It should continue sending after the pull socket will receive the messages. However it will not be after exactly one message, so the pull probably need to handle around 500 messages (or half of the high watermark) in order for the push to continue sending. – somdoron Jan 03 '16 at 10:28
  • 1
    You don't have to do anything, the push socket will continue and try to send the message. Just make sure the PULL handle the messages. – somdoron Jan 03 '16 at 10:29
  • Aah, got it. My consumer is itself sending PUSH messages when it processes the PULL, and the second consumer wasn't reading those messages. I've got the same wrapper around the PUSH socket in both places, so increasing the HWM in the wrapper appeared to resolve the problem by letting the consumer continue even though, unknown to me, its PUSH queue was filling up. In short, this was entirely my fault and NetMQ was doing what it should have - obvious in retrospect, but I'd been scratching my head at that one for hours and your answer prodded me to look in the right place. Thanks for the help! – McSti Jan 03 '16 at 11:14

0 Answers0