add WithOffsetFunc to define private RandomExpireCache.offset field

This commit is contained in:
Kevin Tsang 2022-06-29 14:11:42 +08:00
parent 6edee6c9c9
commit 178440bcdd
2 changed files with 29 additions and 12 deletions

View File

@ -24,29 +24,35 @@ import (
// RandomExpireCacheOption implement genreate random time offset expired option // RandomExpireCacheOption implement genreate random time offset expired option
type RandomExpireCacheOption func(*RandomExpireCache) type RandomExpireCacheOption func(*RandomExpireCache)
// WithOffsetFunc returns a RandomExpireCacheOption that configures the offset function
func WithOffsetFunc(fn func() time.Duration) RandomExpireCacheOption {
return func(cache *RandomExpireCache) {
cache.offset = fn
}
}
// RandomExpireCache prevent cache batch invalidation // RandomExpireCache prevent cache batch invalidation
// Cache random time offset expired // Cache random time offset expired
type RandomExpireCache struct { type RandomExpireCache struct {
Cache Cache
Offset func() time.Duration offset func() time.Duration
} }
// Put random time offset expired // Put random time offset expired
func (rec *RandomExpireCache) Put(ctx context.Context, key string, val interface{}, timeout time.Duration) error { func (rec *RandomExpireCache) Put(ctx context.Context, key string, val interface{}, timeout time.Duration) error {
timeout += rec.Offset() timeout += rec.offset()
return rec.Cache.Put(ctx, key, val, timeout) return rec.Cache.Put(ctx, key, val, timeout)
} }
// NewRandomExpireCache return random expire cache struct // NewRandomExpireCache return random expire cache struct
func NewRandomExpireCache(adapter Cache, opts ...RandomExpireCacheOption) Cache { func NewRandomExpireCache(adapter Cache, opts ...RandomExpireCacheOption) Cache {
var rec RandomExpireCache rec := RandomExpireCache{
rec.Cache = adapter Cache: adapter,
offset: defaultExpiredFunc(),
}
for _, fn := range opts { for _, fn := range opts {
fn(&rec) fn(&rec)
} }
if rec.Offset == nil {
rec.Offset = defaultExpiredFunc()
}
return &rec return &rec
} }

View File

@ -16,6 +16,7 @@ package cache
import ( import (
"context" "context"
"math/rand"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -27,10 +28,9 @@ func TestRandomExpireCache(t *testing.T) {
bm, err := NewCache("memory", `{"interval":20}`) bm, err := NewCache("memory", `{"interval":20}`)
assert.Nil(t, err) assert.Nil(t, err)
// cache := NewRandomExpireCache(bm) cache := NewRandomExpireCache(bm)
cache := NewRandomExpireCache(bm, func(opt *RandomExpireCache) { // should not be nil
opt.Offset = defaultExpiredFunc() assert.NotNil(t, cache.(*RandomExpireCache).offset)
})
timeoutDuration := 3 * time.Second timeoutDuration := 3 * time.Second
@ -84,5 +84,16 @@ func TestRandomExpireCache(t *testing.T) {
assert.NotNil(t, err) assert.NotNil(t, err)
assert.True(t, strings.Contains(err.Error(), "key isn't exist")) assert.True(t, strings.Contains(err.Error(), "key isn't exist"))
}
func TestWithOffsetFunc(t *testing.T) {
bm, err := NewCache("memory", `{"interval":20}`)
assert.Nil(t, err)
magic := -time.Duration(rand.Int())
cache := NewRandomExpireCache(bm, WithOffsetFunc(func() time.Duration {
return magic
}))
// offset should return the magic value
assert.Equal(t, magic, cache.(*RandomExpireCache).offset())
} }