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.
Этот коммит содержится в:
@@ -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
|
||||
|
||||
Ссылка в новой задаче
Block a user