diff --git a/bucket.go b/bucket.go index e8e5a93..a379937 100644 --- a/bucket.go +++ b/bucket.go @@ -59,12 +59,12 @@ func (b *bucket[T]) setnx(key string, value T, duration time.Duration, track boo return newItem } -func (b *bucket[T]) setnx2(key string, f func() T, duration time.Duration, track bool) *Item[T] { +func (b *bucket[T]) setnx2(key string, f func() T, duration time.Duration, track bool) (*Item[T], bool) { b.RLock() item := b.lookup[key] b.RUnlock() if item != nil { - return item + return item, true } b.Lock() @@ -73,14 +73,14 @@ func (b *bucket[T]) setnx2(key string, f func() T, duration time.Duration, track // check again under write lock item = b.lookup[key] if item != nil { - return item + return item, true } expires := time.Now().Add(duration).UnixNano() newItem := newItem(key, f(), expires, track) b.lookup[key] = newItem - return newItem + return newItem, false } func (b *bucket[T]) set(key string, value T, duration time.Duration, track bool) (*Item[T], *Item[T]) { diff --git a/cache.go b/cache.go index b822484..f5414d8 100644 --- a/cache.go +++ b/cache.go @@ -126,8 +126,17 @@ func (c *Cache[T]) Setnx(key string, value T, duration time.Duration) { // Setnx2 set the value in the cache for the specified duration if not exists func (c *Cache[T]) Setnx2(key string, f func() T, duration time.Duration) *Item[T] { - item := c.bucket(key).setnx2(key, f, duration, false) - c.promotables <- item + item, existing := c.bucket(key).setnx2(key, f, duration, false) + // consistent with Get + if existing && !item.Expired() { + select { + case c.promotables <- item: + default: + } + // consistent with set + } else if !existing { + c.promotables <- item + } return item }