Improve Event Broadcaster robustness and feedback on error#265
Improve Event Broadcaster robustness and feedback on error#265aacuevas merged 4 commits intoopen-ephys:developmentfrom
Conversation
…event-broadcaster-robust
|
Added a solution to the actual problem that was causing #264 (...causing me to think it was necessary). It uses a reference counted context object to destroy the context when the last event broadcaster is deleted rather than when the program exits. Sorry if it's too big of a change/too complicated, but it seems to work. |
|
I was just writing about that. Thanks! |
| ScopedLock lock(sharedContextLock); | ||
| sharedContext = nullptr; | ||
| #ifdef ZEROMQ | ||
| zmq_ctx_destroy(context); |
There was a problem hiding this comment.
Maybe would be better to release the lock before calling this (by putting the 2 lines above in their own block). Theoretically all the sockets should be gone if this is being called, but it doesn't hurt and since this call blocks if there are still any alive sockets, there could be some potential for a deadlock.
| #ifdef ZEROMQ | ||
| jassert(context != nullptr); | ||
| return zmq_socket(context, ZMQ_PUB); | ||
| #endif |
There was a problem hiding this comment.
Realized soon after the last commit that there should be a return statement for the case that ZEROMQ isn't defined (would just return nullptr). I have a feeling this would produce at least a warning on Linux.
This incorporates a few changes to try to make the Event Broadcaster more predictable and less frustrating to use:
Previously, the socket would silently fail to bind to the port every other time you clicked "Restart connection" (at least on my machine), due to the old socket not actually closing and freeing the port immediately. This also caused race conditions when loading a signal chain. The issue is discussed here (for the Node.js version): socket.close() is not really synchronous but there is no event to notify when it is really closed JustinTulloss/zeromq.node#214. To solve, as suggested there, I added a call to
zmq_unbindwhich frees the port immediately. The old socket then only gets closed if the new one is bound successfully; otherwise, it gets rebound to the original port.When loading a signal chain, previously the editor would not be updated to show the loaded port. Fixed this by adding a method in the editor to update the displayed port and calling this whenever the port is set.
If 5557 was already in use, a new Event Broadcaster would default to port 0 (invalid), which is not ideal. Instead, changed the constructor to keep looking for a free port if it receives the
EADDRINUSEerror fromsetListeningPort.Made the editor report errors in the status bar if they occur when changing the port or restarting the connection.
I briefly looked at the Network Events plugin as well, but it looks like the code there is substantially different even though the editor's appearance is similar to Event Broadcaster. So I didn't want to get involved with that too given that this is already a medium-sized PR.