More notification metrics fixes (#26889)

* Explicitly have the client tell the server when it should expect an ACK

* Don't count missing profile errors for your own posts, added comment

* Fix test

* Make postedAck a parameter in WebSocketClient

* Snapshot fixes

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
Devin Binnie
2024-04-25 15:07:12 -04:00
коммит произвёл GitHub
родитель 5f1a357845
Коммит 60c15c821f
9 изменённых файлов: 44 добавлений и 24 удалений

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

@@ -17,6 +17,7 @@ import (
const (
connectionIDParam = "connection_id"
sequenceNumberParam = "sequence_number"
postedAckParam = "posted_ack"
)
func (api *API) InitWebSocket() {
@@ -48,6 +49,7 @@ func connectWebSocket(c *Context, w http.ResponseWriter, r *http.Request) {
TFunc: c.AppContext.T,
Locale: "",
Active: true,
PostedAck: r.URL.Query().Get(postedAckParam) == "true",
}
// The WebSocket upgrade request coming from mobile is missing the
// user agent so we need to fallback on the session's metadata.

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

@@ -740,15 +740,19 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
// A user following a thread but had left the channel won't get a notification
// https://mattermost.atlassian.net/browse/MM-36769
if profileMap[uid] == nil {
a.CountNotificationReason(model.NotificationStatusError, model.NotificationTypeWebsocket, model.NotificationReasonMissingProfile)
a.NotificationsLog().Error("Missing profile",
mlog.String("type", model.NotificationTypeWebsocket),
mlog.String("post_id", post.Id),
mlog.String("status", model.NotificationStatusError),
mlog.String("reason", model.NotificationReasonMissingProfile),
mlog.String("sender_id", sender.Id),
mlog.String("receiver_id", uid),
)
// This also sometimes happens when bots, which will never show up in the map, reply to threads
// Their own post goes through this and they get "notified", which we don't need to count as an error if they can't
if uid != post.UserId {
a.CountNotificationReason(model.NotificationStatusError, model.NotificationTypeWebsocket, model.NotificationReasonMissingProfile)
a.NotificationsLog().Error("Missing profile",
mlog.String("type", model.NotificationTypeWebsocket),
mlog.String("post_id", post.Id),
mlog.String("status", model.NotificationStatusError),
mlog.String("reason", model.NotificationReasonMissingProfile),
mlog.String("sender_id", sender.Id),
mlog.String("receiver_id", uid),
)
}
continue
}
if a.IsCRTEnabledForUser(c, uid) {

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

@@ -68,6 +68,7 @@ type WebConnConfig struct {
Active bool
ReuseCount int
OriginClient string
PostedAck bool
// These aren't necessary to be exported to api layer.
sequence int
@@ -89,6 +90,7 @@ type WebConn struct {
Locale string
Sequence int64
UserId string
PostedAck bool
allChannelMembers map[string]string
lastAllChannelMembersTime int64
@@ -234,6 +236,7 @@ func (ps *PlatformService) NewWebConn(cfg *WebConnConfig, suite SuiteIFace, runn
UserId: cfg.Session.UserId,
T: cfg.TFunc,
Locale: cfg.Locale,
PostedAck: cfg.PostedAck,
reuseCount: cfg.ReuseCount,
endWritePump: make(chan struct{}),
pumpFinished: make(chan struct{}),

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

@@ -82,11 +82,9 @@ func usePostedAckHook(message *model.WebSocketEvent, postedUserId string, channe
}
func (h *postedAckBroadcastHook) Process(msg *platform.HookedWebSocketEvent, webConn *platform.WebConn, args map[string]any) error {
// Don't ACK mobile app websocket events at this time, we may revisit this when we can add this to mobile app
if session := webConn.GetSession(); session != nil {
if session.IsMobile() {
return nil
}
// Don't ACK unless we say to explicitly
if !webConn.PostedAck {
return nil
}
postedUserId, err := getTypedArg[string](args, "posted_user_id")

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

@@ -87,8 +87,9 @@ func TestPostedAckHook_Process(t *testing.T) {
hook := &postedAckBroadcastHook{}
userID := model.NewId()
webConn := &platform.WebConn{
UserId: userID,
Platform: &platform.PlatformService{},
UserId: userID,
Platform: &platform.PlatformService{},
PostedAck: true,
}
webConn.SetSession(&model.Session{})
@@ -140,12 +141,12 @@ func TestPostedAckHook_Process(t *testing.T) {
assert.True(t, msg.Event().GetData()["should_ack"].(bool))
})
t.Run("should not ack for mobile app", func(t *testing.T) {
t.Run("should not ack if posted ack is false", func(t *testing.T) {
mobileWebConn := &platform.WebConn{
UserId: userID,
Platform: &platform.PlatformService{},
UserId: userID,
Platform: &platform.PlatformService{},
PostedAck: false,
}
mobileWebConn.SetSession(&model.Session{Props: map[string]string{"isMobile": "true"}})
msg := platform.MakeHookedWebSocketEvent(model.NewWebSocketEvent(model.WebsocketEventPosted, "", "", "", nil, ""))
hook.Process(msg, mobileWebConn, map[string]any{