Reset status to away after web conn disconnect if necessary (#8988)

Этот коммит содержится в:
Joram Wilander
2018-06-27 17:19:06 -04:00
коммит произвёл Christopher Speller
родитель 437f9f5b64
Коммит 2114e96f00
4 изменённых файлов: 68 добавлений и 9 удалений

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

@@ -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 != "" {