frostfs-sdk-go/pool/cache.go
Marina Biryukova 560cbbd1f1 [#234] pool: Update token expiration check in cache
Signed-off-by: Marina Biryukova <m.biryukova@yadro.com>
2024-07-05 12:36:17 +03:00

80 lines
1.7 KiB
Go

package pool
import (
"strings"
"sync/atomic"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
lru "github.com/hashicorp/golang-lru/v2"
)
type sessionCache struct {
cache *lru.Cache[string, *cacheValue]
currentEpoch atomic.Uint64
tokenDuration uint64
}
type cacheValue struct {
token session.Object
}
func newCache(tokenDuration uint64) (*sessionCache, error) {
cache, err := lru.New[string, *cacheValue](100)
if err != nil {
return nil, err
}
return &sessionCache{cache: cache, tokenDuration: tokenDuration}, nil
}
// Get returns a copy of the session token from the cache without signature
// and context related fields. Returns nil if token is missing in the cache.
// It is safe to modify and re-sign returned session token.
func (c *sessionCache) Get(key string) (session.Object, bool) {
value, ok := c.cache.Get(key)
if !ok {
return session.Object{}, false
}
if c.expired(value) {
c.cache.Remove(key)
return session.Object{}, false
}
return value.token, true
}
func (c *sessionCache) Put(key string, token session.Object) bool {
return c.cache.Add(key, &cacheValue{
token: token,
})
}
func (c *sessionCache) DeleteByPrefix(prefix string) {
for _, key := range c.cache.Keys() {
if strings.HasPrefix(key, prefix) {
c.cache.Remove(key)
}
}
}
func (c *sessionCache) updateEpoch(newEpoch uint64) {
epoch := c.currentEpoch.Load()
if newEpoch > epoch {
c.currentEpoch.Store(newEpoch)
}
}
func (c *sessionCache) expired(val *cacheValue) bool {
epoch := c.currentEpoch.Load()
preExpiredDur := c.tokenDuration / 2
if preExpiredDur == 0 {
preExpiredDur = 1
}
return val.token.ExpiredAt(epoch + preExpiredDur)
}
func (c *sessionCache) Epoch() uint64 {
return c.currentEpoch.Load()
}