mirror of
https://github.com/niusmallnan/steve.git
synced 2025-07-01 17:01:54 +00:00
Adding logic to limit number of cached schemas
Adds logic to ensure that only one schema/access set is cached for each user. This should improve memory consumption
This commit is contained in:
parent
dbf9ef88ce
commit
115eb31f57
@ -14,6 +14,7 @@ import (
|
|||||||
|
|
||||||
type AccessSetLookup interface {
|
type AccessSetLookup interface {
|
||||||
AccessFor(user user.Info) *AccessSet
|
AccessFor(user user.Info) *AccessSet
|
||||||
|
PurgeUserData(id string)
|
||||||
}
|
}
|
||||||
|
|
||||||
type AccessStore struct {
|
type AccessStore struct {
|
||||||
@ -63,6 +64,10 @@ func (l *AccessStore) AccessFor(user user.Info) *AccessSet {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *AccessStore) PurgeUserData(id string) {
|
||||||
|
l.cache.Remove(id)
|
||||||
|
}
|
||||||
|
|
||||||
func (l *AccessStore) CacheKey(user user.Info) string {
|
func (l *AccessStore) CacheKey(user user.Info) string {
|
||||||
d := sha256.New()
|
d := sha256.New()
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ type Collection struct {
|
|||||||
byGVR map[schema.GroupVersionResource]string
|
byGVR map[schema.GroupVersionResource]string
|
||||||
byGVK map[schema.GroupVersionKind]string
|
byGVK map[schema.GroupVersionKind]string
|
||||||
cache *cache.LRUExpireCache
|
cache *cache.LRUExpireCache
|
||||||
|
userCache *cache.LRUExpireCache
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
|
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
@ -84,6 +85,7 @@ func NewCollection(ctx context.Context, baseSchema *types.APISchemas, access acc
|
|||||||
byGVR: map[schema.GroupVersionResource]string{},
|
byGVR: map[schema.GroupVersionResource]string{},
|
||||||
byGVK: map[schema.GroupVersionKind]string{},
|
byGVK: map[schema.GroupVersionKind]string{},
|
||||||
cache: cache.NewLRUExpireCache(1000),
|
cache: cache.NewLRUExpireCache(1000),
|
||||||
|
userCache: cache.NewLRUExpireCache(1000),
|
||||||
notifiers: map[int]func(){},
|
notifiers: map[int]func(){},
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
as: access,
|
as: access,
|
||||||
|
@ -23,6 +23,7 @@ func newSchemas() (*types.APISchemas, error) {
|
|||||||
|
|
||||||
func (c *Collection) Schemas(user user.Info) (*types.APISchemas, error) {
|
func (c *Collection) Schemas(user user.Info) (*types.APISchemas, error) {
|
||||||
access := c.as.AccessFor(user)
|
access := c.as.AccessFor(user)
|
||||||
|
c.removeOldRecords(access, user)
|
||||||
val, ok := c.cache.Get(access.ID)
|
val, ok := c.cache.Get(access.ID)
|
||||||
if ok {
|
if ok {
|
||||||
schemas, _ := val.(*types.APISchemas)
|
schemas, _ := val.(*types.APISchemas)
|
||||||
@ -33,11 +34,34 @@ func (c *Collection) Schemas(user user.Info) (*types.APISchemas, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
c.addToCache(access, user, schemas)
|
||||||
c.cache.Add(access.ID, schemas, 24*time.Hour)
|
|
||||||
return schemas, nil
|
return schemas, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Collection) removeOldRecords(access *accesscontrol.AccessSet, user user.Info) {
|
||||||
|
current, ok := c.userCache.Get(user.GetName())
|
||||||
|
if ok {
|
||||||
|
currentId, cOk := current.(string)
|
||||||
|
if cOk && currentId != access.ID {
|
||||||
|
// we only want to keep around one record per user. If our current access record is invalid, purge the
|
||||||
|
//record of it from the cache, so we don't keep duplicates
|
||||||
|
c.purgeUserRecords(currentId)
|
||||||
|
c.userCache.Remove(user.GetName())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Collection) addToCache(access *accesscontrol.AccessSet, user user.Info, schemas *types.APISchemas) {
|
||||||
|
c.cache.Add(access.ID, schemas, 24*time.Hour)
|
||||||
|
c.userCache.Add(user.GetName(), access.ID, 24*time.Hour)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PurgeUserRecords removes a record from the backing LRU cache before expiry
|
||||||
|
func (c *Collection) purgeUserRecords(id string) {
|
||||||
|
c.cache.Remove(id)
|
||||||
|
c.as.PurgeUserData(id)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Collection) schemasForSubject(access *accesscontrol.AccessSet) (*types.APISchemas, error) {
|
func (c *Collection) schemasForSubject(access *accesscontrol.AccessSet) (*types.APISchemas, error) {
|
||||||
c.lock.RLock()
|
c.lock.RLock()
|
||||||
defer c.lock.RUnlock()
|
defer c.lock.RUnlock()
|
||||||
|
Loading…
Reference in New Issue
Block a user