forked from TrueCloudLab/frostfs-s3-gw
85 lines
2.4 KiB
Go
85 lines
2.4 KiB
Go
|
package cache
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"time"
|
||
|
|
||
|
"git.frostfs.info/TrueCloudLab/frostfs-contract/frostfsid/client"
|
||
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
|
||
|
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||
|
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
||
|
"github.com/bluele/gcache"
|
||
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||
|
"go.uber.org/zap"
|
||
|
)
|
||
|
|
||
|
// FrostfsIDCache provides lru cache for frostfsid contract.
|
||
|
type FrostfsIDCache struct {
|
||
|
cache gcache.Cache
|
||
|
logger *zap.Logger
|
||
|
}
|
||
|
|
||
|
type FrostfsIDCacheKey struct {
|
||
|
Target engine.Target
|
||
|
Name chain.Name
|
||
|
}
|
||
|
|
||
|
const (
|
||
|
// DefaultFrostfsIDCacheSize is a default maximum number of entries in cache.
|
||
|
DefaultFrostfsIDCacheSize = 1e4
|
||
|
// DefaultFrostfsIDCacheLifetime is a default lifetime of entries in cache.
|
||
|
DefaultFrostfsIDCacheLifetime = time.Minute
|
||
|
)
|
||
|
|
||
|
// DefaultFrostfsIDConfig returns new default cache expiration values.
|
||
|
func DefaultFrostfsIDConfig(logger *zap.Logger) *Config {
|
||
|
return &Config{
|
||
|
Size: DefaultFrostfsIDCacheSize,
|
||
|
Lifetime: DefaultFrostfsIDCacheLifetime,
|
||
|
Logger: logger,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// NewFrostfsIDCache creates an object of FrostfsIDCache.
|
||
|
func NewFrostfsIDCache(config *Config) *FrostfsIDCache {
|
||
|
gc := gcache.New(config.Size).LRU().Expiration(config.Lifetime).Build()
|
||
|
return &FrostfsIDCache{cache: gc, logger: config.Logger}
|
||
|
}
|
||
|
|
||
|
// GetSubject returns a cached client.SubjectExtended. Returns nil if value is missing.
|
||
|
func (c *FrostfsIDCache) GetSubject(key util.Uint160) *client.SubjectExtended {
|
||
|
return get[client.SubjectExtended](c, key)
|
||
|
}
|
||
|
|
||
|
// PutSubject puts a client.SubjectExtended to cache.
|
||
|
func (c *FrostfsIDCache) PutSubject(key util.Uint160, subject *client.SubjectExtended) error {
|
||
|
return c.cache.Set(key, subject)
|
||
|
}
|
||
|
|
||
|
// GetUserKey returns a cached *keys.PublicKey. Returns nil if value is missing.
|
||
|
func (c *FrostfsIDCache) GetUserKey(ns, name string) *keys.PublicKey {
|
||
|
return get[keys.PublicKey](c, ns+"/"+name)
|
||
|
}
|
||
|
|
||
|
// PutUserKey puts a client.SubjectExtended to cache.
|
||
|
func (c *FrostfsIDCache) PutUserKey(ns, name string, userKey *keys.PublicKey) error {
|
||
|
return c.cache.Set(ns+"/"+name, userKey)
|
||
|
}
|
||
|
|
||
|
func get[T any](c *FrostfsIDCache, key any) *T {
|
||
|
entry, err := c.cache.Get(key)
|
||
|
if err != nil {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
result, ok := entry.(*T)
|
||
|
if !ok {
|
||
|
c.logger.Warn(logs.InvalidCacheEntryType, zap.String("actual", fmt.Sprintf("%T", entry)),
|
||
|
zap.String("expected", fmt.Sprintf("%T", result)))
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
return result
|
||
|
}
|