-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle Q.WATCH updates in a single event loop for Websockets #1175
base: master
Are you sure you want to change the base?
Conversation
@lucifercr07 - Please review. |
Have we done any benchmarking for the Q.Watch and do we want to check if we are not regressing anything with the above change? |
Hey @psrvere could you please resolve the conflicts? |
@JyotinderSingh - Resolved. Please review. |
if err != nil && !errors.Is(err, http.ErrServerClosed) { | ||
slog.Error("error while listenting on WebSocket", slog.Any("error", err)) | ||
} | ||
s.listenForSubscriptions(wsCtx) |
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.
Apologies if I'm missing something here, why do we need a separate go routine to listen for QWATCH
subscriptions? Can't it be handled as part of websocketServer.ListenAndServe()
?
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.
@lucifercr07 - ListenAndServe
receives subscription request which is then handled by WebsocketHandler
. It sends subscription event on subscriptionChan
and a dedicated goroutine listenForSubscriptions
receives the event and subscribes it.
Are you suggesting that we move the work done by listenForSubscriptions
in WebsocketHandler
?
I created it as a separate goroutine to separate the concern. Do you see any disadvantage in this?
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.
May be we can let WebsocketHandler
do the subscription itself, it won't be an expensive/long-running op.
We've already separated processQwatchUpdates
to a separate go-routine.
Commands other than .watch
wouldn't be long-running generally and I feel a single go-routine would be enough to handle the clients.
Unless we see some latency issue may be we can avoid creating new go-routines.
Please let me know if I'm missing something here.
Closes #1153
In PR #1090 Q.WATCH updates were handled by
processQwatchUpdates
run in a goroutine. Based on this review comment, this PR moves this handling to a single event loop. ItsubscriptionChan
andsubscribedClients
toWebsocketServer
listenForSubscriptions
andprocessQwatchUpdates
as part ofWebsocketServer.Run()
shutdownChan
(called by abort command) andctx.Done
channelThis PR also
ReadResponse
function insetup.go
to read Q.WATCH updatesTestQWatchWithMultipleClients
andTestQWatchWithMultipleClientsAndQueries
qwatch_test.go
to be unique so that there is no interference with other tests. Since cancelling subscription (Q.UNWATCH) is not supported yet, any following tests that changes the key also triggers Q.WATCH updates. This is a known issue and will be fixed as part of Add Q.UNWATCH for websocket #1154This PR also fixes following bugs:
conn.WriteMessage
. Fix: added a mutexprocessQwatchUpdates
goroutine. Fix: It skips update when it can't process it and logs error.RunWebsocketServer
insetup.go
was relying on both cancelling parent context to shutdownqueryManager
goroutine and abort command to shutdownshardManager
. Fix: Made it consistent - everythings is gracefully shutdown by abort command