From 2114e96f0045376f41d5c318f7cf45b6b50141dc Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Wed, 27 Jun 2018 17:19:06 -0400 Subject: Reset status to away after web conn disconnect if necessary (#8988) --- app/web_hub.go | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'app/web_hub.go') diff --git a/app/web_hub.go b/app/web_hub.go index 2ce78b5ef..5bb86ee38 100644 --- a/app/web_hub.go +++ b/app/web_hub.go @@ -23,6 +23,12 @@ const ( DEADLOCK_WARN = (BROADCAST_QUEUE_SIZE * 99) / 100 // number of buffered messages before printing stack trace ) +type WebConnActivityMessage struct { + UserId string + SessionToken string + ActivityAt int64 +} + type Hub struct { // connectionCount should be kept first. // See https://github.com/mattermost/mattermost-server/pull/7281 @@ -35,6 +41,7 @@ type Hub struct { stop chan struct{} didStop chan struct{} invalidateUser chan string + activity chan *WebConnActivityMessage ExplicitStop bool goroutineId int } @@ -48,6 +55,7 @@ func (a *App) NewWebHub() *Hub { stop: make(chan struct{}), didStop: make(chan struct{}), invalidateUser: make(chan string), + activity: make(chan *WebConnActivityMessage), ExplicitStop: false, } } @@ -330,6 +338,13 @@ func (a *App) InvalidateWebConnSessionCacheForUser(userId string) { } } +func (a *App) UpdateWebConnUserActivity(session model.Session, activityAt int64) { + hub := a.GetHubForUserId(session.UserId) + if hub != nil { + hub.UpdateActivity(session.UserId, session.Token, activityAt) + } +} + func (h *Hub) Register(webConn *WebConn) { h.register <- webConn @@ -355,6 +370,10 @@ func (h *Hub) InvalidateUser(userId string) { h.invalidateUser <- userId } +func (h *Hub) UpdateActivity(userId, sessionToken string, activityAt int64) { + h.activity <- &WebConnActivityMessage{UserId: userId, SessionToken: sessionToken, ActivityAt: activityAt} +} + func getGoroutineId() int { var buf [64]byte n := runtime.Stack(buf[:], false) @@ -395,15 +414,34 @@ func (h *Hub) Start() { continue } - if len(connections.ForUser(webCon.UserId)) == 0 { + conns := connections.ForUser(webCon.UserId) + if len(conns) == 0 { h.app.Go(func() { h.app.SetStatusOffline(webCon.UserId, false) }) + } else { + var latestActivity int64 = 0 + for _, conn := range conns { + if conn.LastUserActivityAt > latestActivity { + latestActivity = conn.LastUserActivityAt + } + } + if h.app.IsUserAway(latestActivity) { + h.app.Go(func() { + h.app.SetStatusLastActivityAt(webCon.UserId, latestActivity) + }) + } } case userId := <-h.invalidateUser: for _, webCon := range connections.ForUser(userId) { webCon.InvalidateCache() } + case activity := <-h.activity: + for _, webCon := range connections.ForUser(activity.UserId) { + if webCon.GetSessionToken() == activity.SessionToken { + webCon.LastUserActivityAt = activity.ActivityAt + } + } case msg := <-h.broadcast: candidates := connections.All() if msg.Broadcast.UserId != "" { -- cgit v1.2.3-1-g7c22