-
Notifications
You must be signed in to change notification settings - Fork 34
Fix issue where unsubscribing in push_events led to API_EventTimeout … #699
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -698,6 +698,9 @@ bool ZmqEventConsumer::process_ctrl(zmq::message_t &received_ctrl,zmq::pollitem_ | |
{ | ||
bool ret = false; | ||
|
||
// static variable to count the number of ZMQ_DELAY_EVENT requests currently in progress: | ||
static int nb_current_delay_event_requests = 0; | ||
|
||
// | ||
// For debug and logging purposes | ||
// | ||
|
@@ -1075,14 +1078,32 @@ bool ZmqEventConsumer::process_ctrl(zmq::message_t &received_ctrl,zmq::pollitem_ | |
|
||
case ZMQ_DELAY_EVENT: | ||
{ | ||
old_poll_nb = poll_nb; | ||
poll_nb = 1; | ||
// If poll_nb == 1, then we are already in a situation where events are being delayed | ||
// and we are currently only taking care of messages received on the control socket | ||
// No need to update old_poll_nb in this case because it is already correct | ||
// otherwise this would lead to issues like https://github.com/tango-controls/cppTango/issues/686 | ||
// where events would no longer be received if someone subscribes or unsubscribes to events in | ||
// an event callback and when the callback is executed during a subscribe_event call | ||
if (poll_nb != 1) | ||
{ | ||
old_poll_nb = poll_nb; | ||
poll_nb = 1; | ||
Comment on lines
+1089
to
+1090
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can these two variables be completely removed and replaced with just one boolean flag (e.g. this->delay_events = true;)? const int ALL_SOCKETS = 3;
const int ONLY_CONTROL_SOCKET = 1;
zmq::poll(items, delay_events ? ONLY_CONTROL_SOCKET : ALL_SOCKETS, -1) I think this bug would never appear in this case. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I propose to do something like that for tango >= 9.4 (in tango-9-lts branch) because this implies dropping support for multicast events. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for pointing that out! I was not aware that this will impact multicast events (I am not familiar with how those are implemented). |
||
} | ||
nb_current_delay_event_requests++; | ||
} | ||
break; | ||
|
||
case ZMQ_RELEASE_EVENT: | ||
{ | ||
poll_nb = old_poll_nb; | ||
if(nb_current_delay_event_requests >= 1) | ||
{ | ||
nb_current_delay_event_requests--; | ||
} | ||
if(nb_current_delay_event_requests == 0) | ||
{ | ||
// Stop delaying events only if there is no other ZMQ_DELAY_EVENT command requested | ||
poll_nb = old_poll_nb; | ||
} | ||
} | ||
break; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this double-delay scenario, shouldn't we count how many ZMQ_DELAY_EVENTs were received and wait for as many ZMQ_RELEASE_EVENTs?
Can we run into an issue when e.g. two threads create DelatEvent object?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point! I agree with you it would make sense to count the number of received ZMQ_DELAY_EVENTS and really release once we have received as many ZMQ_RELEASE_EVENTS as ZMQ_DELAY_EVENTS.
There might be other issues if we don't do that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mliszcz , I implemented this counter in a5d2c80
In cppTango >= 9.4, we could eventually make this variable a private member of ZmqEventConsumer class.
I didn't do it here to preserve the binary compatibility.
For the moment, this variable is useful/used only in ZmqEventConsumer::process_ctrl() method and the ZMQEventConsumer object is a singleton so it should be fine like this.
Could you please have a look?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! This is exactly what I had in mind.