@@ -489,42 +489,44 @@ void DataProcessingDevice::doPrepare(DataProcessorContext& context)
489489 int64_t result = -2 ;
490490 auto & fairMQChannel = context.device ->GetChannel (channel.name , 0 );
491491 auto & socket = fairMQChannel.GetSocket ();
492- uint32_t events;
493- socket.Events (&events);
494- if ((events & 1 ) == 0 ) {
495- continue ;
492+ // If we have pending events from a previous iteration,
493+ // we do receive in any case.
494+ // Otherwise we check if there is any pending event and skip
495+ // this channel in case there is none.
496+ if (info.hasPendingEvents == 0 ) {
497+ socket.Events (&info.hasPendingEvents );
498+ // If we do not read, we can continue.
499+ if ((info.hasPendingEvents & 1 ) == 0 ) {
500+ continue ;
501+ }
496502 }
497503 // Notice that there seems to be a difference between the documentation
498504 // of zeromq and the observed behavior. The fact that ZMQ_POLLIN
499505 // is raised does not mean that a message is immediately available to
500506 // read, just that it will be available soon, so the receive can
501507 // still return -2. To avoid this we keep receiving on the socket until
502- // we get a message, consume all the consecutive messages, and then go back
503- // to the usual loop.
504- do {
505- if (events & 1 ) {
506- bool oneMessage = false ;
507- while (true ) {
508- FairMQParts parts;
509- result = fairMQChannel.Receive (parts, 0 );
510- if (result >= 0 ) {
511- // Receiving data counts as activity now, so that
512- // We can make sure we process all the pending
513- // messages without hanging on the uv_run.
514- *context.wasActive = true ;
515- DataProcessingDevice::handleData (context, parts, info);
516- oneMessage = true ;
517- } else {
518- if (oneMessage) {
519- break ;
520- }
521- }
522- }
523- } else {
508+ // we get a message. In order not to overflow the DPL queue we process
509+ // one message at the time and we keep track of wether there were more
510+ // to process.
511+ while (true ) {
512+ FairMQParts parts;
513+ result = fairMQChannel.Receive (parts, 0 );
514+ if (result >= 0 ) {
515+ DataProcessingDevice::handleData (context, parts, info);
516+ // Receiving data counts as activity now, so that
517+ // We can make sure we process all the pending
518+ // messages without hanging on the uv_run.
524519 break ;
525520 }
526- socket.Events (&events);
527- } while (events & 1 );
521+ }
522+ // We check once again for pending events, keeping track if this was the
523+ // case so that we can immediately repeat this loop and avoid remaining
524+ // stuck in uv_run. This is because we will not get notified on the socket
525+ // if more events are pending due to zeromq level triggered approach.
526+ socket.Events (&info.hasPendingEvents );
527+ if (info.hasPendingEvents ) {
528+ *context.wasActive |= true ;
529+ }
528530 }
529531}
530532
0 commit comments