websocket: drop less important events before they are queued (#20326)

Discard the non-essential WebSocket events before they are queued.

When conn send queue is full, the connection is closed. There are messages that are being dropped by the current mechanism when send queue is at 50% capacity. This change makes the messages drop before entering the queue in order to keep the queue as empty as possible.

The value of the length of the queue could not be 100% accurate since we are reading from the hub goroutine, but it will be accurate enough to avoid some events.
Этот коммит содержится в:
José Peso
2022-06-14 09:35:22 +02:00
коммит произвёл GitHub
родитель 182ae1234a
Коммит 48a9234d69

Просмотреть файл

@@ -450,27 +450,6 @@ func (wc *WebConn) writePump() {
evt, evtOk := msg.(*model.WebSocketEvent)
skipSend := false
if len(wc.send) >= sendSlowWarn {
// When the pump starts to get slow we'll drop non-critical messages
switch msg.EventType() {
case model.WebsocketEventTyping,
model.WebsocketEventStatusChange,
model.WebsocketEventChannelViewed:
mlog.Warn(
"websocket.slow: dropping message",
mlog.String("user_id", wc.UserId),
mlog.String("type", msg.EventType()),
mlog.String("channel_id", evt.GetBroadcast().ChannelId),
)
skipSend = true
}
}
if skipSend {
continue
}
buf.Reset()
var err error
if evtOk {
@@ -726,6 +705,23 @@ func (wc *WebConn) shouldSendEvent(msg *model.WebSocketEvent) bool {
return false
}
// When the pump starts to get slow we'll drop non-critical
// messages. We should skip those frames before they are
// queued to wc.send buffered channel.
if len(wc.send) >= sendSlowWarn {
switch msg.EventType() {
case model.WebsocketEventTyping,
model.WebsocketEventStatusChange,
model.WebsocketEventChannelViewed:
mlog.Warn(
"websocket.slow: dropping message",
mlog.String("user_id", wc.UserId),
mlog.String("type", msg.EventType()),
)
return false
}
}
// If the event contains sanitized data, only send to users that don't have permission to
// see sensitive data. Prevents admin clients from receiving events with bad data
var hasReadPrivateDataPermission *bool