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.
78 lines
1.6 KiB
78 lines
1.6 KiB
package mw
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync"
|
|
"time"
|
|
|
|
"gitoa.ru/go-4devs/cache"
|
|
)
|
|
|
|
type key struct {
|
|
key interface{}
|
|
ctxPrefix string
|
|
}
|
|
|
|
func (k key) Value() interface{} {
|
|
return k.key
|
|
}
|
|
|
|
func (k key) String() string {
|
|
return fmt.Sprint(k.ctxPrefix, k.key)
|
|
}
|
|
|
|
// WithClearByContext clear cache if context done.
|
|
func WithClearByContext(ctxKey interface{}) cache.Configure {
|
|
operation := func(ctx context.Context, op string, item *cache.Item, next cache.Provider) error {
|
|
ctxPrefix, ok := ctx.Value(ctxKey).(string)
|
|
if !ok {
|
|
return fmt.Errorf("%w: must be unique ctx key", cache.ErrKeyNotValid)
|
|
}
|
|
|
|
k := item.Key.Key
|
|
item.Key.Key = key{
|
|
key: k,
|
|
ctxPrefix: ctxPrefix,
|
|
}
|
|
|
|
return next(ctx, op, item)
|
|
}
|
|
|
|
return cache.WithMiddleware(
|
|
func(ctx context.Context, op string, item *cache.Item, next cache.Provider) error {
|
|
if op == cache.OperationSet {
|
|
go func(ctx context.Context, item *cache.Item) {
|
|
<-ctx.Done()
|
|
_ = next(ctx, cache.OperationDelete, item)
|
|
}(ctx, item)
|
|
}
|
|
|
|
return operation(ctx, op, item, next)
|
|
})
|
|
}
|
|
|
|
// WithClearByTTL clear cache by key after ttl.
|
|
func WithClearByTTL() cache.Configure {
|
|
keys := make(map[cache.Key]*time.Timer)
|
|
mu := sync.Mutex{}
|
|
|
|
return cache.WithHandleSet(func(ctx context.Context, op string, item *cache.Item, next cache.Provider) error {
|
|
if item.TTL > 0 {
|
|
go func() {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
if t, ok := keys[item.Key]; ok {
|
|
t.Reset(item.TTL)
|
|
} else {
|
|
keys[item.Key] = time.AfterFunc(item.TTL, func() {
|
|
_ = next(ctx, cache.OperationDelete, item)
|
|
delete(keys, item.Key)
|
|
})
|
|
}
|
|
}()
|
|
}
|
|
|
|
return next(ctx, op, item)
|
|
})
|
|
}
|
|
|