diff --git a/pool/cache.go b/pool/cache.go index 8b9342a..8eaaefe 100644 --- a/pool/cache.go +++ b/pool/cache.go @@ -2,6 +2,7 @@ package pool import ( "strings" + "time" lru "github.com/hashicorp/golang-lru" "github.com/nspcc-dev/neofs-sdk-go/session" @@ -11,6 +12,11 @@ type SessionCache struct { cache *lru.Cache } +type cacheValue struct { + atime time.Time + token *session.Token +} + func NewCache() (*SessionCache, error) { cache, err := lru.New(100) if err != nil { @@ -21,15 +27,31 @@ func NewCache() (*SessionCache, error) { } func (c *SessionCache) Get(key string) *session.Token { - tokenRaw, ok := c.cache.Get(key) + valueRaw, ok := c.cache.Get(key) if !ok { return nil } - return tokenRaw.(*session.Token) + + value := valueRaw.(*cacheValue) + value.atime = time.Now() + + return value.token +} + +func (c *SessionCache) GetAccessTime(key string) (time.Time, bool) { + valueRaw, ok := c.cache.Peek(key) + if !ok { + return time.Time{}, false + } + + return valueRaw.(*cacheValue).atime, true } func (c *SessionCache) Put(key string, token *session.Token) bool { - return c.cache.Add(key, token) + return c.cache.Add(key, &cacheValue{ + atime: time.Now(), + token: token, + }) } func (c *SessionCache) DeleteByPrefix(prefix string) { diff --git a/pool/cache_test.go b/pool/cache_test.go new file mode 100644 index 0000000..63350c9 --- /dev/null +++ b/pool/cache_test.go @@ -0,0 +1,31 @@ +package pool + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestSessionCache_GetAccessTime(t *testing.T) { + const key = "Foo" + + cache, err := NewCache() + require.NoError(t, err) + + cache.Put(key, nil) + + t1, ok := cache.GetAccessTime(key) + require.True(t, ok) + + time.Sleep(10 * time.Millisecond) + + t2, ok := cache.GetAccessTime(key) + require.True(t, ok) + require.Equal(t, t1, t2) + + _ = cache.Get(key) + t3, ok := cache.GetAccessTime(key) + require.True(t, ok) + require.NotEqual(t, t1, t3) +}