pool: Update token expiration check in cache #234

Merged
alexvanin merged 1 commit from mbiryukova/frostfs-sdk-go:bugfix/token_expiration into master 2024-07-08 08:56:04 +00:00
4 changed files with 19 additions and 10 deletions

View file

@ -9,21 +9,22 @@ import (
) )
type sessionCache struct { type sessionCache struct {
cache *lru.Cache[string, *cacheValue] cache *lru.Cache[string, *cacheValue]
currentEpoch atomic.Uint64 currentEpoch atomic.Uint64
tokenDuration uint64
} }
type cacheValue struct { type cacheValue struct {
token session.Object token session.Object
} }
func newCache() (*sessionCache, error) { func newCache(tokenDuration uint64) (*sessionCache, error) {
cache, err := lru.New[string, *cacheValue](100) cache, err := lru.New[string, *cacheValue](100)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &sessionCache{cache: cache}, nil return &sessionCache{cache: cache, tokenDuration: tokenDuration}, nil
} }
// Get returns a copy of the session token from the cache without signature // Get returns a copy of the session token from the cache without signature
@ -66,8 +67,12 @@ func (c *sessionCache) updateEpoch(newEpoch uint64) {
func (c *sessionCache) expired(val *cacheValue) bool { func (c *sessionCache) expired(val *cacheValue) bool {
epoch := c.currentEpoch.Load() epoch := c.currentEpoch.Load()
// use epoch+1 (clear cache beforehand) to prevent 'expired session token' error right after epoch tick preExpiredDur := c.tokenDuration / 2
Review

I don't understand. If the lifetime of the session token in the cache is 10 epochs, then why will it be removed from the cache at epoch 95, and not 100?

I don't understand. If the lifetime of the session token in the cache is 10 epochs, then why will it be removed from the cache at epoch 95, and not 100?
Review

To avoid errors if epoch increases between sending request to storage and its processing (which can occur now)
cc @alexvanin

To avoid errors if epoch increases between sending request to storage and its processing (which can occur now) cc @alexvanin
return val.token.ExpiredAt(epoch + 1) if preExpiredDur == 0 {
preExpiredDur = 1
}
return val.token.ExpiredAt(epoch + preExpiredDur)
} }
func (c *sessionCache) Epoch() uint64 { func (c *sessionCache) Epoch() uint64 {

View file

@ -20,7 +20,7 @@ func TestSessionCache_GetUnmodifiedToken(t *testing.T) {
require.False(t, tok.VerifySignature(), extra) require.False(t, tok.VerifySignature(), extra)
} }
cache, err := newCache() cache, err := newCache(0)
require.NoError(t, err) require.NoError(t, err)
cache.Put(key, target) cache.Put(key, target)

View file

@ -1947,7 +1947,7 @@ type innerPool struct {
} }
const ( const (
defaultSessionTokenExpirationDuration = 100 // in blocks defaultSessionTokenExpirationDuration = 100 // in epochs
defaultErrorThreshold = 100 defaultErrorThreshold = 100
defaultRebalanceInterval = 15 * time.Second defaultRebalanceInterval = 15 * time.Second
@ -1969,7 +1969,7 @@ func NewPool(options InitParameters) (*Pool, error) {
return nil, err return nil, err
} }
cache, err := newCache() cache, err := newCache(options.sessionExpirationDuration)
if err != nil { if err != nil {
return nil, fmt.Errorf("couldn't create cache: %w", err) return nil, fmt.Errorf("couldn't create cache: %w", err)
} }
@ -2087,6 +2087,10 @@ func fillDefaultInitParams(params *InitParameters, cache *sessionCache) {
params.nodeStreamTimeout = defaultStreamTimeout params.nodeStreamTimeout = defaultStreamTimeout
} }
if cache.tokenDuration == 0 {
cache.tokenDuration = defaultSessionTokenExpirationDuration
}
if params.isMissingClientBuilder() { if params.isMissingClientBuilder() {
params.setClientBuilder(func(addr string) client { params.setClientBuilder(func(addr string) client {
var prm wrapperPrm var prm wrapperPrm

View file

@ -47,7 +47,7 @@ func TestHealthyReweight(t *testing.T) {
buffer = make([]float64, len(weights)) buffer = make([]float64, len(weights))
) )
cache, err := newCache() cache, err := newCache(0)
require.NoError(t, err) require.NoError(t, err)
client1 := newMockClient(names[0], *newPrivateKey(t)) client1 := newMockClient(names[0], *newPrivateKey(t))