PLT-4853 Adding cache purging to the server (server) (#4735)
* PLT-4853 Adding caching invalidation to HA * PLT-4853 Adding cach purging to the server
Этот коммит содержится в:
коммит произвёл
Harrison Healey
родитель
7acd135e02
Коммит
c4974374d9
19
api/admin.go
19
api/admin.go
@@ -31,6 +31,7 @@ func InitAdmin() {
|
|||||||
BaseRoutes.Admin.Handle("/config", ApiAdminSystemRequired(getConfig)).Methods("GET")
|
BaseRoutes.Admin.Handle("/config", ApiAdminSystemRequired(getConfig)).Methods("GET")
|
||||||
BaseRoutes.Admin.Handle("/save_config", ApiAdminSystemRequired(saveConfig)).Methods("POST")
|
BaseRoutes.Admin.Handle("/save_config", ApiAdminSystemRequired(saveConfig)).Methods("POST")
|
||||||
BaseRoutes.Admin.Handle("/reload_config", ApiAdminSystemRequired(reloadConfig)).Methods("GET")
|
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("/test_email", ApiAdminSystemRequired(testEmail)).Methods("POST")
|
||||||
BaseRoutes.Admin.Handle("/recycle_db_conn", ApiAdminSystemRequired(recycleDatabaseConnection)).Methods("GET")
|
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")
|
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)
|
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) {
|
func saveConfig(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||||
cfg := model.ConfigFromJson(r.Body)
|
cfg := model.ConfigFromJson(r.Body)
|
||||||
if cfg == nil {
|
if cfg == nil {
|
||||||
|
|||||||
@@ -116,6 +116,18 @@ func TestReloadConfig(t *testing.T) {
|
|||||||
*utils.Cfg.TeamSettings.EnableOpenServer = true
|
*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) {
|
func TestSaveConfig(t *testing.T) {
|
||||||
th := Setup().InitBasic().InitSystemAdmin()
|
th := Setup().InitBasic().InitSystemAdmin()
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import (
|
|||||||
|
|
||||||
"github.com/mattermost/platform/einterfaces"
|
"github.com/mattermost/platform/einterfaces"
|
||||||
"github.com/mattermost/platform/model"
|
"github.com/mattermost/platform/model"
|
||||||
|
"github.com/mattermost/platform/store"
|
||||||
"github.com/mattermost/platform/utils"
|
"github.com/mattermost/platform/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -514,3 +515,11 @@ func RemoveAllSessionsForUserIdSkipClusterSend(userId string) {
|
|||||||
func AddSessionToCache(session *model.Session) {
|
func AddSessionToCache(session *model.Session) {
|
||||||
sessionCache.AddWithExpiresInSecs(session.Token, session, int64(*utils.Cfg.ServiceSettings.SessionCacheInMinutes*60))
|
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()
|
||||||
|
}
|
||||||
|
|||||||
@@ -251,8 +251,8 @@ func getAuthorizedApps(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
func RevokeAccessToken(token string) *model.AppError {
|
func RevokeAccessToken(token string) *model.AppError {
|
||||||
|
|
||||||
|
session := GetSession(token)
|
||||||
schan := Srv.Store.Session().Remove(token)
|
schan := Srv.Store.Session().Remove(token)
|
||||||
sessionCache.Remove(token)
|
|
||||||
|
|
||||||
if result := <-Srv.Store.OAuth().GetAccessData(token); result.Err != nil {
|
if result := <-Srv.Store.OAuth().GetAccessData(token); result.Err != nil {
|
||||||
return model.NewLocAppError("RevokeAccessToken", "api.oauth.revoke_access_token.get.app_error", 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, "")
|
return model.NewLocAppError("RevokeAccessToken", "api.oauth.revoke_access_token.del_session.app_error", nil, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if session != nil {
|
||||||
|
RemoveAllSessionsForUserId(session.UserId)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ import (
|
|||||||
|
|
||||||
var statusCache *utils.Cache = utils.NewLru(model.STATUS_CACHE_SIZE)
|
var statusCache *utils.Cache = utils.NewLru(model.STATUS_CACHE_SIZE)
|
||||||
|
|
||||||
|
func ClearStatusCache() {
|
||||||
|
statusCache.Purge()
|
||||||
|
}
|
||||||
|
|
||||||
func AddStatusCacheSkipClusterSend(status *model.Status) {
|
func AddStatusCacheSkipClusterSend(status *model.Status) {
|
||||||
statusCache.Add(status.UserId, status)
|
statusCache.Add(status.UserId, status)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -458,12 +458,11 @@ func revokeAllSessions(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
if session.IsOAuth {
|
if session.IsOAuth {
|
||||||
RevokeAccessToken(session.Token)
|
RevokeAccessToken(session.Token)
|
||||||
} else {
|
} else {
|
||||||
sessionCache.Remove(session.Token)
|
|
||||||
|
|
||||||
if result := <-Srv.Store.Session().Remove(session.Id); result.Err != nil {
|
if result := <-Srv.Store.Session().Remove(session.Id); result.Err != nil {
|
||||||
c.Err = result.Err
|
c.Err = result.Err
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
|
RemoveAllSessionsForUserId(session.UserId)
|
||||||
w.Write([]byte(model.MapToJson(props)))
|
w.Write([]byte(model.MapToJson(props)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
c.Session.SetExpireInDays(*utils.Cfg.ServiceSettings.SessionLengthMobileInDays)
|
||||||
|
|
||||||
maxAge := *utils.Cfg.ServiceSettings.SessionLengthMobileInDays * 60 * 60 * 24
|
maxAge := *utils.Cfg.ServiceSettings.SessionLengthMobileInDays * 60 * 60 * 24
|
||||||
@@ -756,18 +756,13 @@ func RevokeSessionById(c *Context, sessionId string) {
|
|||||||
if session.IsOAuth {
|
if session.IsOAuth {
|
||||||
RevokeAccessToken(session.Token)
|
RevokeAccessToken(session.Token)
|
||||||
} else {
|
} else {
|
||||||
sessionCache.Remove(session.Token)
|
|
||||||
|
|
||||||
if result := <-Srv.Store.Session().Remove(session.Id); result.Err != nil {
|
if result := <-Srv.Store.Session().Remove(session.Id); result.Err != nil {
|
||||||
c.Err = result.Err
|
c.Err = result.Err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RevokeWebrtcToken(session.Id)
|
RevokeWebrtcToken(session.Id)
|
||||||
|
RemoveAllSessionsForUserId(session.UserId)
|
||||||
if einterfaces.GetClusterInterface() != nil {
|
|
||||||
einterfaces.GetClusterInterface().RemoveAllSessionsForUserId(session.UserId)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ type ClusterInterface interface {
|
|||||||
GetLogs() ([]string, *model.AppError)
|
GetLogs() ([]string, *model.AppError)
|
||||||
GetClusterId() string
|
GetClusterId() string
|
||||||
ConfigChanged(previousConfig *model.Config, newConfig *model.Config, sendToOtherServer bool) *model.AppError
|
ConfigChanged(previousConfig *model.Config, newConfig *model.Config, sendToOtherServer bool) *model.AppError
|
||||||
|
InvalidateAllCaches() *model.AppError
|
||||||
}
|
}
|
||||||
|
|
||||||
var theClusterInterface ClusterInterface
|
var theClusterInterface ClusterInterface
|
||||||
|
|||||||
@@ -683,6 +683,10 @@
|
|||||||
"id": "api.context.invalid_token.error",
|
"id": "api.context.invalid_token.error",
|
||||||
"translation": "Invalid session token=%v, err=%v"
|
"translation": "Invalid session token=%v, err=%v"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "api.context.invalidate_all_caches",
|
||||||
|
"translation": "Purging all caches"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "api.context.last_activity_at.error",
|
"id": "api.context.last_activity_at.error",
|
||||||
"translation": "Failed to update LastActivityAt for user_id=%v and session_id=%v, err=%v"
|
"translation": "Failed to update LastActivityAt for user_id=%v and session_id=%v, err=%v"
|
||||||
|
|||||||
@@ -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) {
|
func (c *Client) SaveConfig(config *Config) (*Result, *AppError) {
|
||||||
if r, err := c.DoApiPost("/admin/save_config", config.ToJson()); err != nil {
|
if r, err := c.DoApiPost("/admin/save_config", config.ToJson()); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -33,6 +33,11 @@ type SqlChannelStore struct {
|
|||||||
var channelMemberCountsCache = utils.NewLru(CHANNEL_MEMBERS_COUNTS_CACHE_SIZE)
|
var channelMemberCountsCache = utils.NewLru(CHANNEL_MEMBERS_COUNTS_CACHE_SIZE)
|
||||||
var allChannelMembersForUserCache = utils.NewLru(ALL_CHANNEL_MEMBERS_FOR_USER_CACHE_SIZE)
|
var allChannelMembersForUserCache = utils.NewLru(ALL_CHANNEL_MEMBERS_FOR_USER_CACHE_SIZE)
|
||||||
|
|
||||||
|
func ClearChannelCaches() {
|
||||||
|
channelMemberCountsCache.Purge()
|
||||||
|
allChannelMembersForUserCache.Purge()
|
||||||
|
}
|
||||||
|
|
||||||
func NewSqlChannelStore(sqlStore *SqlStore) ChannelStore {
|
func NewSqlChannelStore(sqlStore *SqlStore) ChannelStore {
|
||||||
s := &SqlChannelStore{sqlStore}
|
s := &SqlChannelStore{sqlStore}
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,10 @@ type SqlUserStore struct {
|
|||||||
|
|
||||||
var profilesInChannelCache *utils.Cache = utils.NewLru(PROFILES_IN_CHANNEL_CACHE_SIZE)
|
var profilesInChannelCache *utils.Cache = utils.NewLru(PROFILES_IN_CHANNEL_CACHE_SIZE)
|
||||||
|
|
||||||
|
func ClearUserCaches() {
|
||||||
|
profilesInChannelCache.Purge()
|
||||||
|
}
|
||||||
|
|
||||||
func NewSqlUserStore(sqlStore *SqlStore) UserStore {
|
func NewSqlUserStore(sqlStore *SqlStore) UserStore {
|
||||||
us := &SqlUserStore{sqlStore}
|
us := &SqlUserStore{sqlStore}
|
||||||
|
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user