Move caches to manager #1553
56
caches/manager.go
Normal file
56
caches/manager.go
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
// Copyright 2020 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package caches
|
||||||
|
|
||||||
|
import "sync"
|
||||||
|
|
||||||
|
type Manager struct {
|
||||||
|
cacher Cacher
|
||||||
|
disableGlobalCache bool
|
||||||
|
|
||||||
|
cachers map[string]Cacher
|
||||||
|
cacherLock sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewManager() *Manager {
|
||||||
|
return &Manager{
|
||||||
|
cachers: make(map[string]Cacher),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDisableGlobalCache disable global cache or not
|
||||||
|
func (mgr *Manager) SetDisableGlobalCache(disable bool) {
|
||||||
|
if mgr.disableGlobalCache != disable {
|
||||||
|
mgr.disableGlobalCache = disable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mgr *Manager) SetCacher(tableName string, cacher Cacher) {
|
||||||
|
mgr.cacherLock.Lock()
|
||||||
|
mgr.cachers[tableName] = cacher
|
||||||
|
mgr.cacherLock.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mgr *Manager) GetCacher(tableName string) Cacher {
|
||||||
|
var cacher Cacher
|
||||||
|
var ok bool
|
||||||
|
mgr.cacherLock.RLock()
|
||||||
|
cacher, ok = mgr.cachers[tableName]
|
||||||
|
mgr.cacherLock.RUnlock()
|
||||||
|
if !ok && !mgr.disableGlobalCache {
|
||||||
|
cacher = mgr.cacher
|
||||||
|
}
|
||||||
|
return cacher
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDefaultCacher set the default cacher. Xorm's default not enable cacher.
|
||||||
|
func (mgr *Manager) SetDefaultCacher(cacher Cacher) {
|
||||||
|
mgr.cacher = cacher
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDefaultCacher returns the default cacher
|
||||||
|
func (mgr *Manager) GetDefaultCacher() Cacher {
|
||||||
|
return mgr.cacher
|
||||||
|
}
|
53
engine.go
53
engine.go
|
@ -41,7 +41,6 @@ type Engine struct {
|
||||||
Tables map[reflect.Type]*schemas.Table
|
Tables map[reflect.Type]*schemas.Table
|
||||||
|
|
||||||
mutex *sync.RWMutex
|
mutex *sync.RWMutex
|
||||||
Cacher caches.Cacher
|
|
||||||
|
|
||||||
showSQL bool
|
showSQL bool
|
||||||
showExecTime bool
|
showExecTime bool
|
||||||
|
@ -50,42 +49,20 @@ type Engine struct {
|
||||||
TZLocation *time.Location // The timezone of the application
|
TZLocation *time.Location // The timezone of the application
|
||||||
DatabaseTZ *time.Location // The timezone of the database
|
DatabaseTZ *time.Location // The timezone of the database
|
||||||
|
|
||||||
disableGlobalCache bool
|
|
||||||
|
|
||||||
tagHandlers map[string]tagHandler
|
tagHandlers map[string]tagHandler
|
||||||
|
|
||||||
engineGroup *EngineGroup
|
engineGroup *EngineGroup
|
||||||
|
cacherMgr *caches.Manager
|
||||||
cachers map[string]caches.Cacher
|
|
||||||
cacherLock sync.RWMutex
|
|
||||||
|
|
||||||
defaultContext context.Context
|
defaultContext context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
func (engine *Engine) setCacher(tableName string, cacher caches.Cacher) {
|
|
||||||
engine.cacherLock.Lock()
|
|
||||||
engine.cachers[tableName] = cacher
|
|
||||||
engine.cacherLock.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (engine *Engine) SetCacher(tableName string, cacher caches.Cacher) {
|
func (engine *Engine) SetCacher(tableName string, cacher caches.Cacher) {
|
||||||
engine.setCacher(tableName, cacher)
|
engine.cacherMgr.SetCacher(tableName, cacher)
|
||||||
}
|
|
||||||
|
|
||||||
func (engine *Engine) getCacher(tableName string) caches.Cacher {
|
|
||||||
var cacher caches.Cacher
|
|
||||||
var ok bool
|
|
||||||
engine.cacherLock.RLock()
|
|
||||||
cacher, ok = engine.cachers[tableName]
|
|
||||||
engine.cacherLock.RUnlock()
|
|
||||||
if !ok && !engine.disableGlobalCache {
|
|
||||||
cacher = engine.Cacher
|
|
||||||
}
|
|
||||||
return cacher
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (engine *Engine) GetCacher(tableName string) caches.Cacher {
|
func (engine *Engine) GetCacher(tableName string) caches.Cacher {
|
||||||
return engine.getCacher(tableName)
|
return engine.cacherMgr.GetCacher(tableName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BufferSize sets buffer size for iterate
|
// BufferSize sets buffer size for iterate
|
||||||
|
@ -152,9 +129,7 @@ func (engine *Engine) SetLogLevel(level log.LogLevel) {
|
||||||
|
|
||||||
// SetDisableGlobalCache disable global cache or not
|
// SetDisableGlobalCache disable global cache or not
|
||||||
func (engine *Engine) SetDisableGlobalCache(disable bool) {
|
func (engine *Engine) SetDisableGlobalCache(disable bool) {
|
||||||
if engine.disableGlobalCache != disable {
|
engine.cacherMgr.SetDisableGlobalCache(disable)
|
||||||
engine.disableGlobalCache = disable
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DriverName return the current sql driver's name
|
// DriverName return the current sql driver's name
|
||||||
|
@ -244,12 +219,12 @@ func (engine *Engine) SetMaxIdleConns(conns int) {
|
||||||
|
|
||||||
// SetDefaultCacher set the default cacher. Xorm's default not enable cacher.
|
// SetDefaultCacher set the default cacher. Xorm's default not enable cacher.
|
||||||
func (engine *Engine) SetDefaultCacher(cacher caches.Cacher) {
|
func (engine *Engine) SetDefaultCacher(cacher caches.Cacher) {
|
||||||
engine.Cacher = cacher
|
engine.cacherMgr.SetDefaultCacher(cacher)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDefaultCacher returns the default cacher
|
// GetDefaultCacher returns the default cacher
|
||||||
func (engine *Engine) GetDefaultCacher() caches.Cacher {
|
func (engine *Engine) GetDefaultCacher() caches.Cacher {
|
||||||
return engine.Cacher
|
return engine.cacherMgr.GetDefaultCacher()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NoCache If you has set default cacher, and you want temporilly stop use cache,
|
// NoCache If you has set default cacher, and you want temporilly stop use cache,
|
||||||
|
@ -269,7 +244,7 @@ func (engine *Engine) NoCascade() *Session {
|
||||||
|
|
||||||
// MapCacher Set a table use a special cacher
|
// MapCacher Set a table use a special cacher
|
||||||
func (engine *Engine) MapCacher(bean interface{}, cacher caches.Cacher) error {
|
func (engine *Engine) MapCacher(bean interface{}, cacher caches.Cacher) error {
|
||||||
engine.setCacher(engine.TableName(bean, true), cacher)
|
engine.SetCacher(engine.TableName(bean, true), cacher)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -799,7 +774,7 @@ func (engine *Engine) autoMapType(v reflect.Value) (*schemas.Table, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
engine.Tables[t] = table
|
engine.Tables[t] = table
|
||||||
if engine.Cacher != nil {
|
if engine.GetDefaultCacher() != nil {
|
||||||
if v.CanAddr() {
|
if v.CanAddr() {
|
||||||
engine.GobRegister(v.Addr().Interface())
|
engine.GobRegister(v.Addr().Interface())
|
||||||
} else {
|
} else {
|
||||||
|
@ -1030,17 +1005,17 @@ func (engine *Engine) mapType(v reflect.Value) (*schemas.Table, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if hasCacheTag {
|
if hasCacheTag {
|
||||||
if engine.Cacher != nil { // !nash! use engine's cacher if provided
|
if engine.GetDefaultCacher() != nil { // !nash! use engine's cacher if provided
|
||||||
engine.logger.Info("enable cache on table:", table.Name)
|
engine.logger.Info("enable cache on table:", table.Name)
|
||||||
engine.setCacher(table.Name, engine.Cacher)
|
engine.SetCacher(table.Name, engine.GetDefaultCacher())
|
||||||
} else {
|
} else {
|
||||||
engine.logger.Info("enable LRU cache on table:", table.Name)
|
engine.logger.Info("enable LRU cache on table:", table.Name)
|
||||||
engine.setCacher(table.Name, caches.NewLRUCacher2(caches.NewMemoryStore(), time.Hour, 10000))
|
engine.SetCacher(table.Name, caches.NewLRUCacher2(caches.NewMemoryStore(), time.Hour, 10000))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if hasNoCacheTag {
|
if hasNoCacheTag {
|
||||||
engine.logger.Info("disable cache on table:", table.Name)
|
engine.logger.Info("disable cache on table:", table.Name)
|
||||||
engine.setCacher(table.Name, nil)
|
engine.SetCacher(table.Name, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
return table, nil
|
return table, nil
|
||||||
|
@ -1152,7 +1127,7 @@ func (engine *Engine) CreateUniques(bean interface{}) error {
|
||||||
// ClearCacheBean if enabled cache, clear the cache bean
|
// ClearCacheBean if enabled cache, clear the cache bean
|
||||||
func (engine *Engine) ClearCacheBean(bean interface{}, id string) error {
|
func (engine *Engine) ClearCacheBean(bean interface{}, id string) error {
|
||||||
tableName := engine.TableName(bean)
|
tableName := engine.TableName(bean)
|
||||||
cacher := engine.getCacher(tableName)
|
cacher := engine.GetCacher(tableName)
|
||||||
if cacher != nil {
|
if cacher != nil {
|
||||||
cacher.ClearIds(tableName)
|
cacher.ClearIds(tableName)
|
||||||
cacher.DelBean(tableName, id)
|
cacher.DelBean(tableName, id)
|
||||||
|
@ -1164,7 +1139,7 @@ func (engine *Engine) ClearCacheBean(bean interface{}, id string) error {
|
||||||
func (engine *Engine) ClearCache(beans ...interface{}) error {
|
func (engine *Engine) ClearCache(beans ...interface{}) error {
|
||||||
for _, bean := range beans {
|
for _, bean := range beans {
|
||||||
tableName := engine.TableName(bean)
|
tableName := engine.TableName(bean)
|
||||||
cacher := engine.getCacher(tableName)
|
cacher := engine.GetCacher(tableName)
|
||||||
if cacher != nil {
|
if cacher != nil {
|
||||||
cacher.ClearIds(tableName)
|
cacher.ClearIds(tableName)
|
||||||
cacher.ClearBeans(tableName)
|
cacher.ClearBeans(tableName)
|
||||||
|
|
|
@ -28,7 +28,7 @@ func (session *Session) cacheDelete(table *schemas.Table, tableName, sqlStr stri
|
||||||
return ErrCacheFailed
|
return ErrCacheFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
cacher := session.engine.getCacher(tableName)
|
cacher := session.engine.GetCacher(tableName)
|
||||||
pkColumns := table.PKColumns()
|
pkColumns := table.PKColumns()
|
||||||
ids, err := caches.GetCacheSql(cacher, tableName, newsql, args)
|
ids, err := caches.GetCacheSql(cacher, tableName, newsql, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -206,7 +206,7 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if cacher := session.engine.getCacher(tableNameNoQuote); cacher != nil && session.statement.UseCache {
|
if cacher := session.engine.GetCacher(tableNameNoQuote); cacher != nil && session.statement.UseCache {
|
||||||
session.cacheDelete(table, tableNameNoQuote, deleteSQL, argsForCache...)
|
session.cacheDelete(table, tableNameNoQuote, deleteSQL, argsForCache...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -183,7 +183,7 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
if session.canCache() {
|
if session.canCache() {
|
||||||
if cacher := session.engine.getCacher(session.statement.TableName()); cacher != nil &&
|
if cacher := session.engine.GetCacher(session.statement.TableName()); cacher != nil &&
|
||||||
!session.statement.IsDistinct &&
|
!session.statement.IsDistinct &&
|
||||||
!session.statement.unscoped {
|
!session.statement.unscoped {
|
||||||
err = session.cacheFind(sliceElementType, sqlStr, rowsSlicePtr, args...)
|
err = session.cacheFind(sliceElementType, sqlStr, rowsSlicePtr, args...)
|
||||||
|
@ -329,7 +329,7 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
|
||||||
}
|
}
|
||||||
|
|
||||||
tableName := session.statement.TableName()
|
tableName := session.statement.TableName()
|
||||||
cacher := session.engine.getCacher(tableName)
|
cacher := session.engine.GetCacher(tableName)
|
||||||
if cacher == nil {
|
if cacher == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ func (session *Session) get(bean interface{}) (bool, error) {
|
||||||
table := session.statement.RefTable
|
table := session.statement.RefTable
|
||||||
|
|
||||||
if session.canCache() && beanValue.Elem().Kind() == reflect.Struct {
|
if session.canCache() && beanValue.Elem().Kind() == reflect.Struct {
|
||||||
if cacher := session.engine.getCacher(session.statement.TableName()); cacher != nil &&
|
if cacher := session.engine.GetCacher(session.statement.TableName()); cacher != nil &&
|
||||||
!session.statement.unscoped {
|
!session.statement.unscoped {
|
||||||
has, err := session.cacheGet(bean, sqlStr, args...)
|
has, err := session.cacheGet(bean, sqlStr, args...)
|
||||||
if err != ErrCacheFailed {
|
if err != ErrCacheFailed {
|
||||||
|
@ -280,7 +280,7 @@ func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interf
|
||||||
}
|
}
|
||||||
|
|
||||||
tableName := session.statement.TableName()
|
tableName := session.statement.TableName()
|
||||||
cacher := session.engine.getCacher(tableName)
|
cacher := session.engine.GetCacher(tableName)
|
||||||
|
|
||||||
session.engine.logger.Debug("[cache] Get SQL:", newsql, args)
|
session.engine.logger.Debug("[cache] Get SQL:", newsql, args)
|
||||||
table := session.statement.RefTable
|
table := session.statement.RefTable
|
||||||
|
|
|
@ -613,7 +613,7 @@ func (session *Session) cacheInsert(table string) error {
|
||||||
if !session.statement.UseCache {
|
if !session.statement.UseCache {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cacher := session.engine.getCacher(table)
|
cacher := session.engine.GetCacher(table)
|
||||||
if cacher == nil {
|
if cacher == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ func (session *Session) cacheUpdate(table *schemas.Table, tableName, sqlStr stri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cacher := session.engine.getCacher(tableName)
|
cacher := session.engine.GetCacher(tableName)
|
||||||
session.engine.logger.Debug("[cacheUpdate] get cache sql", newsql, args[nStart:])
|
session.engine.logger.Debug("[cacheUpdate] get cache sql", newsql, args[nStart:])
|
||||||
ids, err := caches.GetCacheSql(cacher, tableName, newsql, args[nStart:])
|
ids, err := caches.GetCacheSql(cacher, tableName, newsql, args[nStart:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -412,7 +412,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cacher := session.engine.getCacher(tableName); cacher != nil && session.statement.UseCache {
|
if cacher := session.engine.GetCacher(tableName); cacher != nil && session.statement.UseCache {
|
||||||
// session.cacheUpdate(table, tableName, sqlStr, args...)
|
// session.cacheUpdate(table, tableName, sqlStr, args...)
|
||||||
session.engine.logger.Debug("[cacheUpdate] clear table ", tableName)
|
session.engine.logger.Debug("[cacheUpdate] clear table ", tableName)
|
||||||
cacher.ClearIds(tableName)
|
cacher.ClearIds(tableName)
|
||||||
|
|
2
xorm.go
2
xorm.go
|
@ -68,8 +68,8 @@ func NewEngine(driverName string, dataSourceName string) (*Engine, error) {
|
||||||
TagIdentifier: "xorm",
|
TagIdentifier: "xorm",
|
||||||
TZLocation: time.Local,
|
TZLocation: time.Local,
|
||||||
tagHandlers: defaultTagHandlers,
|
tagHandlers: defaultTagHandlers,
|
||||||
cachers: make(map[string]caches.Cacher),
|
|
||||||
defaultContext: context.Background(),
|
defaultContext: context.Background(),
|
||||||
|
cacherMgr: caches.NewManager(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if uri.DBType == schemas.SQLITE {
|
if uri.DBType == schemas.SQLITE {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user