You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
66 lines
1.1 KiB
66 lines
1.1 KiB
package lru
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
lru "github.com/hashicorp/golang-lru"
|
|
"gitoa.ru/go-4devs/cache"
|
|
)
|
|
|
|
// New create new lru cache provider.
|
|
func New(client *lru.Cache) cache.Provider {
|
|
return func(ctx context.Context, operation string, item *cache.Item) error {
|
|
switch operation {
|
|
case cache.OperationGet:
|
|
val, ok := client.Get(item.Key)
|
|
if !ok {
|
|
return wrapErr(cache.ErrCacheMiss)
|
|
}
|
|
|
|
it, _ := val.(expired)
|
|
|
|
if !it.ex.IsZero() {
|
|
item.TTL = time.Until(it.ex)
|
|
}
|
|
|
|
if item.IsExpired() {
|
|
return wrapErr(cache.ErrCacheExpired)
|
|
}
|
|
|
|
return wrapErr(cache.TypeAssert(it.value, item.Value))
|
|
case cache.OperationSet:
|
|
it := expired{
|
|
value: item.Value,
|
|
ex: time.Time{},
|
|
}
|
|
if item.TTL > 0 {
|
|
it.ex = item.Expired()
|
|
}
|
|
|
|
_ = client.Add(item.Key, it)
|
|
|
|
return nil
|
|
case cache.OperationDelete:
|
|
_ = client.Remove(item.Key)
|
|
|
|
return nil
|
|
}
|
|
|
|
return wrapErr(cache.ErrOperationNotAllwed)
|
|
}
|
|
}
|
|
|
|
type expired struct {
|
|
ex time.Time
|
|
value interface{}
|
|
}
|
|
|
|
func wrapErr(err error) error {
|
|
if err != nil {
|
|
return fmt.Errorf("%w: lru", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|