summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/admin.go19
-rw-r--r--api/admin_test.go12
-rw-r--r--api/context.go9
-rw-r--r--api/oauth.go6
-rw-r--r--api/status.go4
-rw-r--r--api/team.go3
-rw-r--r--api/user.go9
-rw-r--r--einterfaces/cluster.go1
-rw-r--r--i18n/en.json4
-rw-r--r--model/client.go10
-rw-r--r--store/sql_channel_store.go5
-rw-r--r--store/sql_user_store.go4
12 files changed, 76 insertions, 10 deletions
diff --git a/api/admin.go b/api/admin.go
index d371d2515..20e5075b2 100644
--- a/api/admin.go
+++ b/api/admin.go
@@ -31,6 +31,7 @@ func InitAdmin() {
BaseRoutes.Admin.Handle("/config", ApiAdminSystemRequired(getConfig)).Methods("GET")
BaseRoutes.Admin.Handle("/save_config", ApiAdminSystemRequired(saveConfig)).Methods("POST")
BaseRoutes.Admin.Handle("/reload_config", ApiAdminSystemRequired(reloadConfig)).Methods("GET")
+ BaseRoutes.Admin.Handle("/invalidate_all_caches", ApiAdminSystemRequired(invalidateAllCaches)).Methods("GET")
BaseRoutes.Admin.Handle("/test_email", ApiAdminSystemRequired(testEmail)).Methods("POST")
BaseRoutes.Admin.Handle("/recycle_db_conn", ApiAdminSystemRequired(recycleDatabaseConnection)).Methods("GET")
BaseRoutes.Admin.Handle("/analytics/{id:[A-Za-z0-9]+}/{name:[A-Za-z0-9_]+}", ApiAdminSystemRequired(getAnalytics)).Methods("GET")
@@ -145,6 +146,24 @@ func reloadConfig(c *Context, w http.ResponseWriter, r *http.Request) {
ReturnStatusOK(w)
}
+func invalidateAllCaches(c *Context, w http.ResponseWriter, r *http.Request) {
+ debug.FreeOSMemory()
+
+ InvalidateAllCaches()
+
+ if einterfaces.GetClusterInterface() != nil {
+ err := einterfaces.GetClusterInterface().InvalidateAllCaches()
+ if err != nil {
+ c.Err = err
+ return
+ }
+
+ }
+
+ w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
+ ReturnStatusOK(w)
+}
+
func saveConfig(c *Context, w http.ResponseWriter, r *http.Request) {
cfg := model.ConfigFromJson(r.Body)
if cfg == nil {
diff --git a/api/admin_test.go b/api/admin_test.go
index e1520877c..e11835380 100644
--- a/api/admin_test.go
+++ b/api/admin_test.go
@@ -116,6 +116,18 @@ func TestReloadConfig(t *testing.T) {
*utils.Cfg.TeamSettings.EnableOpenServer = true
}
+func TestInvalidateAllCache(t *testing.T) {
+ th := Setup().InitBasic().InitSystemAdmin()
+
+ if _, err := th.BasicClient.InvalidateAllCaches(); err == nil {
+ t.Fatal("Shouldn't have permissions")
+ }
+
+ if _, err := th.SystemAdminClient.InvalidateAllCaches(); err != nil {
+ t.Fatal(err)
+ }
+}
+
func TestSaveConfig(t *testing.T) {
th := Setup().InitBasic().InitSystemAdmin()
diff --git a/api/context.go b/api/context.go
index 3a867624b..4c2e9d489 100644
--- a/api/context.go
+++ b/api/context.go
@@ -17,6 +17,7 @@ import (
"github.com/mattermost/platform/einterfaces"
"github.com/mattermost/platform/model"
+ "github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
)
@@ -514,3 +515,11 @@ func RemoveAllSessionsForUserIdSkipClusterSend(userId string) {
func AddSessionToCache(session *model.Session) {
sessionCache.AddWithExpiresInSecs(session.Token, session, int64(*utils.Cfg.ServiceSettings.SessionCacheInMinutes*60))
}
+
+func InvalidateAllCaches() {
+ l4g.Info(utils.T("api.context.invalidate_all_caches"))
+ sessionCache.Purge()
+ ClearStatusCache()
+ store.ClearChannelCaches()
+ store.ClearUserCaches()
+}
diff --git a/api/oauth.go b/api/oauth.go
index 233ae0879..08c763b61 100644
--- a/api/oauth.go
+++ b/api/oauth.go
@@ -251,8 +251,8 @@ func getAuthorizedApps(c *Context, w http.ResponseWriter, r *http.Request) {
func RevokeAccessToken(token string) *model.AppError {
+ session := GetSession(token)
schan := Srv.Store.Session().Remove(token)
- sessionCache.Remove(token)
if result := <-Srv.Store.OAuth().GetAccessData(token); result.Err != nil {
return model.NewLocAppError("RevokeAccessToken", "api.oauth.revoke_access_token.get.app_error", nil, "")
@@ -268,6 +268,10 @@ func RevokeAccessToken(token string) *model.AppError {
return model.NewLocAppError("RevokeAccessToken", "api.oauth.revoke_access_token.del_session.app_error", nil, "")
}
+ if session != nil {
+ RemoveAllSessionsForUserId(session.UserId)
+ }
+
return nil
}
diff --git a/api/status.go b/api/status.go
index 897102a4b..a3d419862 100644
--- a/api/status.go
+++ b/api/status.go
@@ -16,6 +16,10 @@ import (
var statusCache *utils.Cache = utils.NewLru(model.STATUS_CACHE_SIZE)
+func ClearStatusCache() {
+ statusCache.Purge()
+}
+
func AddStatusCacheSkipClusterSend(status *model.Status) {
statusCache.Add(status.UserId, status)
}
diff --git a/api/team.go b/api/team.go
index eb184285d..3fc367ac0 100644
--- a/api/team.go
+++ b/api/team.go
@@ -458,12 +458,11 @@ func revokeAllSessions(c *Context, w http.ResponseWriter, r *http.Request) {
if session.IsOAuth {
RevokeAccessToken(session.Token)
} else {
- sessionCache.Remove(session.Token)
-
if result := <-Srv.Store.Session().Remove(session.Id); result.Err != nil {
c.Err = result.Err
return
} else {
+ RemoveAllSessionsForUserId(session.UserId)
w.Write([]byte(model.MapToJson(props)))
return
}
diff --git a/api/user.go b/api/user.go
index 5c92cf47a..2085ccb60 100644
--- a/api/user.go
+++ b/api/user.go
@@ -715,7 +715,7 @@ func attachDeviceId(c *Context, w http.ResponseWriter, r *http.Request) {
}
}
- sessionCache.Remove(c.Session.Token)
+ RemoveAllSessionsForUserId(c.Session.UserId)
c.Session.SetExpireInDays(*utils.Cfg.ServiceSettings.SessionLengthMobileInDays)
maxAge := *utils.Cfg.ServiceSettings.SessionLengthMobileInDays * 60 * 60 * 24
@@ -756,18 +756,13 @@ func RevokeSessionById(c *Context, sessionId string) {
if session.IsOAuth {
RevokeAccessToken(session.Token)
} else {
- sessionCache.Remove(session.Token)
-
if result := <-Srv.Store.Session().Remove(session.Id); result.Err != nil {
c.Err = result.Err
}
}
RevokeWebrtcToken(session.Id)
-
- if einterfaces.GetClusterInterface() != nil {
- einterfaces.GetClusterInterface().RemoveAllSessionsForUserId(session.UserId)
- }
+ RemoveAllSessionsForUserId(session.UserId)
}
}
diff --git a/einterfaces/cluster.go b/einterfaces/cluster.go
index 30a1af103..43ce46280 100644
--- a/einterfaces/cluster.go
+++ b/einterfaces/cluster.go
@@ -19,6 +19,7 @@ type ClusterInterface interface {
GetLogs() ([]string, *model.AppError)
GetClusterId() string
ConfigChanged(previousConfig *model.Config, newConfig *model.Config, sendToOtherServer bool) *model.AppError
+ InvalidateAllCaches() *model.AppError
}
var theClusterInterface ClusterInterface
diff --git a/i18n/en.json b/i18n/en.json
index 928353c10..33e3887b3 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -684,6 +684,10 @@
"translation": "Invalid session token=%v, err=%v"
},
{
+ "id": "api.context.invalidate_all_caches",
+ "translation": "Purging all caches"
+ },
+ {
"id": "api.context.last_activity_at.error",
"translation": "Failed to update LastActivityAt for user_id=%v and session_id=%v, err=%v"
},
diff --git a/model/client.go b/model/client.go
index f782940d8..53b1887a0 100644
--- a/model/client.go
+++ b/model/client.go
@@ -974,6 +974,16 @@ func (c *Client) ReloadConfig() (bool, *AppError) {
}
}
+func (c *Client) InvalidateAllCaches() (bool, *AppError) {
+ c.clearExtraProperties()
+ if r, err := c.DoApiGet("/admin/invalidate_all_caches", "", ""); err != nil {
+ return false, err
+ } else {
+ c.fillInExtraProperties(r)
+ return c.CheckStatusOK(r), nil
+ }
+}
+
func (c *Client) SaveConfig(config *Config) (*Result, *AppError) {
if r, err := c.DoApiPost("/admin/save_config", config.ToJson()); err != nil {
return nil, err
diff --git a/store/sql_channel_store.go b/store/sql_channel_store.go
index e6b7b80bf..3ce672a68 100644
--- a/store/sql_channel_store.go
+++ b/store/sql_channel_store.go
@@ -33,6 +33,11 @@ type SqlChannelStore struct {
var channelMemberCountsCache = utils.NewLru(CHANNEL_MEMBERS_COUNTS_CACHE_SIZE)
var allChannelMembersForUserCache = utils.NewLru(ALL_CHANNEL_MEMBERS_FOR_USER_CACHE_SIZE)
+func ClearChannelCaches() {
+ channelMemberCountsCache.Purge()
+ allChannelMembersForUserCache.Purge()
+}
+
func NewSqlChannelStore(sqlStore *SqlStore) ChannelStore {
s := &SqlChannelStore{sqlStore}
diff --git a/store/sql_user_store.go b/store/sql_user_store.go
index c8c6714d8..3fddfb77d 100644
--- a/store/sql_user_store.go
+++ b/store/sql_user_store.go
@@ -35,6 +35,10 @@ type SqlUserStore struct {
var profilesInChannelCache *utils.Cache = utils.NewLru(PROFILES_IN_CHANNEL_CACHE_SIZE)
+func ClearUserCaches() {
+ profilesInChannelCache.Purge()
+}
+
func NewSqlUserStore(sqlStore *SqlStore) UserStore {
us := &SqlUserStore{sqlStore}