4

If you are using multiple threads to send data over a socket, it is recommended to use NetMQQueue to synchronize these requests.

I've attached the queue to a poller and I'm receiving queue.ReceiveReady events. But in this event I get access to the underlying ConcurrentQueue instance. But I'm not sure what to do with this queue, should i take just one item out of it or should i try to empty it?

//Should I dequeue one item
private static void Queue_ReceiveReady(object sender, NetMQQueueEventArgs<NetMQMessage> e) {
    var item = e.Queue.Dequeue();
    socket.SendMultipartMessage(message);
}

//or all items available
private static void Queue_ReceiveReady(object sender, NetMQQueueEventArgs<NetMQMessage> e) {
    NetMQMessage message;
    while (e.Queue.TryDequeue(out message, TimeSpan.FromMilliseconds(10))) {
        socket.SendMultipartMessage(message);
    }
}

Now to my second question. I've checked the queue implementation and seen that it is just using a lock around the send method of underlying pair socket. So why should I use NetMQQueue, if i could simply use a lock around my send method too, reducing the overhead of an additional pair socket?

public void Send(NetMQMessage data) {
    lock (lockobj) {
        client.SendMultipartMessage(data);
    }
}

I know, following the docs, I should add an additional inproc-Router socket and one DEALER for each thread, to synchronize outgoing calls. But I'm a little bit afraid of having too much overhead, compared to handling the synchronization myself. I expect up to 20 communication threads inside my application, two-way async communication.

communication diagram

dwonisch
  • 5,595
  • 2
  • 30
  • 43
  • Sorry, my image is wrong. IPC should be INPROC – dwonisch Jan 18 '17 at 21:21
  • 1
    Regarding the first question, you can optimize and fetch everything with TryDequeue, you can also fetch only one item – somdoron Jan 22 '17 at 13:50
  • 1
    Emptying the queue yield better performance – somdoron Jan 22 '17 at 13:51
  • 1
    Using lock with NetMQ is not safe, you can fail with it (you can only lock if you only send or only receive and not on a router). However NetMQQueue is using it right and saves you from understanding the internals. Also the implementation of NetMQQueue can actually be optimized, and only lock when the queue is not empty, it is hard to implement and the performance are good right now, so no need. – somdoron Jan 22 '17 at 13:55
  • What should be the ideal timeout to use with `TryDeque`? This is a required parameter and is critical as every Receive_Ready will have to wait for this minimum timeout after the last message has been dequeued. For example if ReceiveReady is triggered 1000 times and I use 10 milliseconds of timeout, it would take 10*1000 milliseconds (10 seconds) of extra time. What is the right way to do it? @somdoron – shashwat Mar 31 '20 at 16:32

0 Answers0