forked from TrueCloudLab/frostfs-s3-gw
109 lines
3.4 KiB
Go
109 lines
3.4 KiB
Go
package cache
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
|
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
|
"github.com/bluele/gcache"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type (
|
|
// ListMultipartSessionCache contains cache for list multiparts session (during pagination).
|
|
ListMultipartSessionCache struct {
|
|
cache gcache.Cache
|
|
logger *zap.Logger
|
|
}
|
|
|
|
// ListMultipartSessionKey is a key to find a ListMultipartSessionCache's entry.
|
|
ListMultipartSessionKey struct {
|
|
cid cid.ID
|
|
prefix string
|
|
marker string
|
|
uploadID string
|
|
}
|
|
)
|
|
|
|
const (
|
|
// DefaultListMultipartSessionCacheLifetime is a default lifetime of entries in cache of ListMultipartUploads.
|
|
DefaultListMultipartSessionCacheLifetime = time.Minute
|
|
// DefaultListMultipartSessionCacheSize is a default size of cache of ListMultipartUploads.
|
|
DefaultListMultipartSessionCacheSize = 100
|
|
)
|
|
|
|
// DefaultListMultipartSessionConfig returns new default cache expiration values.
|
|
func DefaultListMultipartSessionConfig(logger *zap.Logger) *Config {
|
|
return &Config{
|
|
Size: DefaultListMultipartSessionCacheSize,
|
|
Lifetime: DefaultListMultipartSessionCacheLifetime,
|
|
Logger: logger,
|
|
}
|
|
}
|
|
|
|
func (k *ListMultipartSessionKey) String() string {
|
|
return k.cid.EncodeToString() + k.prefix + k.marker + k.uploadID
|
|
}
|
|
|
|
// NewListMultipartSessionCache is a constructor which creates an object of ListObjectsCache with the given lifetime of entries.
|
|
func NewListMultipartSessionCache(config *Config) *ListMultipartSessionCache {
|
|
gc := gcache.New(config.Size).LRU().Expiration(config.Lifetime).EvictedFunc(func(_ interface{}, val interface{}) {
|
|
session, ok := val.(*data.ListMultipartSession)
|
|
if !ok {
|
|
config.Logger.Warn(logs.InvalidCacheEntryType, zap.String("actual", fmt.Sprintf("%T", val)),
|
|
zap.String("expected", fmt.Sprintf("%T", session)))
|
|
}
|
|
|
|
if !session.Acquired.Load() {
|
|
session.Cancel()
|
|
}
|
|
}).Build()
|
|
return &ListMultipartSessionCache{cache: gc, logger: config.Logger}
|
|
}
|
|
|
|
// GetListMultipartSession returns a session of ListMultipartUploads request.
|
|
func (l *ListMultipartSessionCache) GetListMultipartSession(key ListMultipartSessionKey) *data.ListMultipartSession {
|
|
entry, err := l.cache.Get(key)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
result, ok := entry.(*data.ListMultipartSession)
|
|
if !ok {
|
|
l.logger.Warn(logs.InvalidCacheEntryType, zap.String("actual", fmt.Sprintf("%T", entry)),
|
|
zap.String("expected", fmt.Sprintf("%T", result)))
|
|
return nil
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
// PutListMultipartSession puts a ListMultipartUploads session info to cache.
|
|
func (l *ListMultipartSessionCache) PutListMultipartSession(key ListMultipartSessionKey, session *data.ListMultipartSession) error {
|
|
s := l.GetListMultipartSession(key)
|
|
if s != nil && s != session {
|
|
if !s.Acquired.Load() {
|
|
s.Cancel()
|
|
}
|
|
}
|
|
return l.cache.Set(key, session)
|
|
}
|
|
|
|
// DeleteListMultipartSession removes key from cache.
|
|
func (l *ListMultipartSessionCache) DeleteListMultipartSession(key ListMultipartSessionKey) {
|
|
l.cache.Remove(key)
|
|
}
|
|
|
|
// CreateListMultipartSessionCacheKey returns ListMultipartSessionKey with the given CID, prefix, marker and uploadID.
|
|
func CreateListMultipartSessionCacheKey(cnr cid.ID, prefix, marker, uploadID string) ListMultipartSessionKey {
|
|
p := ListMultipartSessionKey{
|
|
cid: cnr,
|
|
prefix: prefix,
|
|
marker: marker,
|
|
uploadID: uploadID,
|
|
}
|
|
|
|
return p
|
|
}
|