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 {
|
||||
AccessFor(user user.Info) *AccessSet
|
||||
PurgeUserData(id string)
|
||||
}
|
||||
|
||||
type AccessStore struct {
|
||||
@ -63,6 +64,10 @@ func (l *AccessStore) AccessFor(user user.Info) *AccessSet {
|
||||
return result
|
||||
}
|
||||
|
||||
func (l *AccessStore) PurgeUserData(id string) {
|
||||
l.cache.Remove(id)
|
||||
}
|
||||
|
||||
func (l *AccessStore) CacheKey(user user.Info) string {
|
||||
d := sha256.New()
|
||||
|
||||
|
@ -36,6 +36,7 @@ type Collection struct {
|
||||
byGVR map[schema.GroupVersionResource]string
|
||||
byGVK map[schema.GroupVersionKind]string
|
||||
cache *cache.LRUExpireCache
|
||||
userCache *cache.LRUExpireCache
|
||||
lock sync.RWMutex
|
||||
|
||||
ctx context.Context
|
||||
@ -84,6 +85,7 @@ func NewCollection(ctx context.Context, baseSchema *types.APISchemas, access acc
|
||||
byGVR: map[schema.GroupVersionResource]string{},
|
||||
byGVK: map[schema.GroupVersionKind]string{},
|
||||
cache: cache.NewLRUExpireCache(1000),
|
||||
userCache: cache.NewLRUExpireCache(1000),
|
||||
notifiers: map[int]func(){},
|
||||
ctx: ctx,
|
||||
as: access,
|
||||
|
@ -23,6 +23,7 @@ func newSchemas() (*types.APISchemas, error) {
|
||||
|
||||
func (c *Collection) Schemas(user user.Info) (*types.APISchemas, error) {
|
||||
access := c.as.AccessFor(user)
|
||||
c.removeOldRecords(access, user)
|
||||
val, ok := c.cache.Get(access.ID)
|
||||
if ok {
|
||||
schemas, _ := val.(*types.APISchemas)
|
||||
@ -33,11 +34,34 @@ func (c *Collection) Schemas(user user.Info) (*types.APISchemas, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c.cache.Add(access.ID, schemas, 24*time.Hour)
|
||||
c.addToCache(access, user, schemas)
|
||||
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) {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
|
Loading…
Reference in New Issue
Block a user