summaryrefslogtreecommitdiffstats
path: root/api/status.go
diff options
context:
space:
mode:
Diffstat (limited to 'api/status.go')
-rw-r--r--api/status.go257
1 files changed, 7 insertions, 250 deletions
diff --git a/api/status.go b/api/status.go
index 909ab50ec..69f391f47 100644
--- a/api/status.go
+++ b/api/status.go
@@ -8,67 +8,30 @@ import (
l4g "github.com/alecthomas/log4go"
- "github.com/mattermost/platform/einterfaces"
+ "github.com/mattermost/platform/app"
"github.com/mattermost/platform/model"
- "github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
)
-var statusCache *utils.Cache = utils.NewLru(model.STATUS_CACHE_SIZE)
-
-func ClearStatusCache() {
- statusCache.Purge()
-}
-
-func AddStatusCacheSkipClusterSend(status *model.Status) {
- statusCache.Add(status.UserId, status)
-}
-
-func AddStatusCache(status *model.Status) {
- AddStatusCacheSkipClusterSend(status)
-
- if einterfaces.GetClusterInterface() != nil {
- einterfaces.GetClusterInterface().UpdateStatus(status)
- }
-}
-
func InitStatus() {
l4g.Debug(utils.T("api.status.init.debug"))
BaseRoutes.Users.Handle("/status", ApiUserRequired(getStatusesHttp)).Methods("GET")
BaseRoutes.Users.Handle("/status/ids", ApiUserRequired(getStatusesByIdsHttp)).Methods("POST")
- BaseRoutes.WebSocket.Handle("get_statuses", ApiWebSocketHandler(getStatusesWebSocket))
- BaseRoutes.WebSocket.Handle("get_statuses_by_ids", ApiWebSocketHandler(getStatusesByIdsWebSocket))
+ app.Srv.WebSocketRouter.Handle("get_statuses", ApiWebSocketHandler(getStatusesWebSocket))
+ app.Srv.WebSocketRouter.Handle("get_statuses_by_ids", ApiWebSocketHandler(getStatusesByIdsWebSocket))
}
func getStatusesHttp(c *Context, w http.ResponseWriter, r *http.Request) {
- statusMap := model.StatusMapToInterfaceMap(GetAllStatuses())
+ statusMap := model.StatusMapToInterfaceMap(app.GetAllStatuses())
w.Write([]byte(model.StringInterfaceToJson(statusMap)))
}
func getStatusesWebSocket(req *model.WebSocketRequest) (map[string]interface{}, *model.AppError) {
- statusMap := GetAllStatuses()
+ statusMap := app.GetAllStatuses()
return model.StatusMapToInterfaceMap(statusMap), nil
}
-func GetAllStatuses() map[string]*model.Status {
- userIds := statusCache.Keys()
- statusMap := map[string]*model.Status{}
-
- for _, userId := range userIds {
- if id, ok := userId.(string); !ok {
- continue
- } else {
- status := GetStatusFromCache(id)
- if status != nil {
- statusMap[id] = status
- }
- }
- }
-
- return statusMap
-}
-
func getStatusesByIdsHttp(c *Context, w http.ResponseWriter, r *http.Request) {
userIds := model.ArrayFromJson(r.Body)
@@ -77,7 +40,7 @@ func getStatusesByIdsHttp(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
- statusMap, err := GetStatusesByIds(userIds)
+ statusMap, err := app.GetStatusesByIds(userIds)
if err != nil {
c.Err = err
return
@@ -93,216 +56,10 @@ func getStatusesByIdsWebSocket(req *model.WebSocketRequest) (map[string]interfac
return nil, NewInvalidWebSocketParamError(req.Action, "user_ids")
}
- statusMap, err := GetStatusesByIds(userIds)
+ statusMap, err := app.GetStatusesByIds(userIds)
if err != nil {
return nil, err
}
return statusMap, nil
}
-
-func GetStatusesByIds(userIds []string) (map[string]interface{}, *model.AppError) {
- statusMap := map[string]interface{}{}
- metrics := einterfaces.GetMetricsInterface()
-
- missingUserIds := []string{}
- for _, userId := range userIds {
- if result, ok := statusCache.Get(userId); ok {
- statusMap[userId] = result.(*model.Status).Status
- if metrics != nil {
- metrics.IncrementMemCacheHitCounter("Status")
- }
- } else {
- missingUserIds = append(missingUserIds, userId)
- if metrics != nil {
- metrics.IncrementMemCacheMissCounter("Status")
- }
- }
- }
-
- if len(missingUserIds) > 0 {
- if result := <-Srv.Store.Status().GetByIds(missingUserIds); result.Err != nil {
- return nil, result.Err
- } else {
- statuses := result.Data.([]*model.Status)
-
- for _, s := range statuses {
- AddStatusCache(s)
- statusMap[s.UserId] = s.Status
- }
- }
- }
-
- // For the case where the user does not have a row in the Status table and cache
- for _, userId := range missingUserIds {
- if _, ok := statusMap[userId]; !ok {
- statusMap[userId] = model.STATUS_OFFLINE
- }
- }
-
- return statusMap, nil
-}
-
-func SetStatusOnline(userId string, sessionId string, manual bool) {
- broadcast := false
-
- var oldStatus string = model.STATUS_OFFLINE
- var oldTime int64 = 0
- var oldManual bool = false
- var status *model.Status
- var err *model.AppError
-
- if status, err = GetStatus(userId); err != nil {
- status = &model.Status{userId, model.STATUS_ONLINE, false, model.GetMillis(), ""}
- broadcast = true
- } else {
- if status.Manual && !manual {
- return // manually set status always overrides non-manual one
- }
-
- if status.Status != model.STATUS_ONLINE {
- broadcast = true
- }
-
- oldStatus = status.Status
- oldTime = status.LastActivityAt
- oldManual = status.Manual
-
- status.Status = model.STATUS_ONLINE
- status.Manual = false // for "online" there's no manual setting
- status.LastActivityAt = model.GetMillis()
- }
-
- AddStatusCache(status)
-
- // Only update the database if the status has changed, the status has been manually set,
- // or enough time has passed since the previous action
- if status.Status != oldStatus || status.Manual != oldManual || status.LastActivityAt-oldTime > model.STATUS_MIN_UPDATE_TIME {
- achan := Srv.Store.Session().UpdateLastActivityAt(sessionId, status.LastActivityAt)
-
- var schan store.StoreChannel
- if broadcast {
- schan = Srv.Store.Status().SaveOrUpdate(status)
- } else {
- schan = Srv.Store.Status().UpdateLastActivityAt(status.UserId, status.LastActivityAt)
- }
-
- if result := <-achan; result.Err != nil {
- l4g.Error(utils.T("api.status.last_activity.error"), userId, sessionId, result.Err)
- }
-
- if result := <-schan; result.Err != nil {
- l4g.Error(utils.T("api.status.save_status.error"), userId, result.Err)
- }
- }
-
- if broadcast {
- event := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_STATUS_CHANGE, "", "", status.UserId, nil)
- event.Add("status", model.STATUS_ONLINE)
- event.Add("user_id", status.UserId)
- go Publish(event)
- }
-}
-
-func SetStatusOffline(userId string, manual bool) {
- status, err := GetStatus(userId)
- if err == nil && status.Manual && !manual {
- return // manually set status always overrides non-manual one
- }
-
- status = &model.Status{userId, model.STATUS_OFFLINE, manual, model.GetMillis(), ""}
-
- AddStatusCache(status)
-
- if result := <-Srv.Store.Status().SaveOrUpdate(status); result.Err != nil {
- l4g.Error(utils.T("api.status.save_status.error"), userId, result.Err)
- }
-
- event := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_STATUS_CHANGE, "", "", status.UserId, nil)
- event.Add("status", model.STATUS_OFFLINE)
- event.Add("user_id", status.UserId)
- go Publish(event)
-}
-
-func SetStatusAwayIfNeeded(userId string, manual bool) {
- status, err := GetStatus(userId)
-
- if err != nil {
- status = &model.Status{userId, model.STATUS_OFFLINE, manual, 0, ""}
- }
-
- if !manual && status.Manual {
- return // manually set status always overrides non-manual one
- }
-
- if !manual {
- if status.Status == model.STATUS_AWAY {
- return
- }
-
- if !IsUserAway(status.LastActivityAt) {
- return
- }
- }
-
- status.Status = model.STATUS_AWAY
- status.Manual = manual
- status.ActiveChannel = ""
-
- AddStatusCache(status)
-
- if result := <-Srv.Store.Status().SaveOrUpdate(status); result.Err != nil {
- l4g.Error(utils.T("api.status.save_status.error"), userId, result.Err)
- }
-
- event := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_STATUS_CHANGE, "", "", status.UserId, nil)
- event.Add("status", model.STATUS_AWAY)
- event.Add("user_id", status.UserId)
- go Publish(event)
-}
-
-func GetStatusFromCache(userId string) *model.Status {
- if result, ok := statusCache.Get(userId); ok {
- status := result.(*model.Status)
- statusCopy := &model.Status{}
- *statusCopy = *status
- return statusCopy
- }
-
- return nil
-}
-
-func GetStatus(userId string) (*model.Status, *model.AppError) {
- status := GetStatusFromCache(userId)
- if status != nil {
- return status, nil
- }
-
- if result := <-Srv.Store.Status().Get(userId); result.Err != nil {
- return nil, result.Err
- } else {
- return result.Data.(*model.Status), nil
- }
-}
-
-func IsUserAway(lastActivityAt int64) bool {
- return model.GetMillis()-lastActivityAt >= *utils.Cfg.TeamSettings.UserStatusAwayTimeout*1000
-}
-
-func DoesStatusAllowPushNotification(user *model.User, status *model.Status, channelId string) bool {
- props := user.NotifyProps
-
- if props["push"] == "none" {
- return false
- }
-
- if pushStatus, ok := props["push_status"]; (pushStatus == model.STATUS_ONLINE || !ok) && (status.ActiveChannel != channelId || model.GetMillis()-status.LastActivityAt > model.STATUS_CHANNEL_TIMEOUT) {
- return true
- } else if pushStatus == model.STATUS_AWAY && (status.Status == model.STATUS_AWAY || status.Status == model.STATUS_OFFLINE) {
- return true
- } else if pushStatus == model.STATUS_OFFLINE && status.Status == model.STATUS_OFFLINE {
- return true
- }
-
- return false
-}