diff --git a/README.md b/README.md index 07f495e..7977f99 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,14 @@ func main() { fmt.Println("Error retrieving value from cache:", err) } + // You can also retrieve Value without affecting it's keep alive + res, err := cache.ValueOnly("someKey") + if err == nil { + fmt.Println("Found value in cache:", res.Data().(*myStruct).text) + } else { + fmt.Println("Error retrieving value from cache:", err) + } + // Wait for the item to expire in cache. time.Sleep(6 * time.Second) res, err = cache.Value("someKey") diff --git a/cache_test.go b/cache_test.go index e195e93..a590e2b 100644 --- a/cache_test.go +++ b/cache_test.go @@ -59,6 +59,7 @@ func TestCacheExpire(t *testing.T) { table.Add(k+"_1", 250*time.Millisecond, v+"_1") table.Add(k+"_2", 200*time.Millisecond, v+"_2") + table.Add(k+"_3", 200*time.Millisecond, v+"_3") time.Sleep(100 * time.Millisecond) @@ -68,6 +69,12 @@ func TestCacheExpire(t *testing.T) { t.Error("Error retrieving value from cache:", err) } + // check key `3`: valueOnly does not extend keep alive + _, err = table.ValueOnly(k + "_3") + if err != nil { + t.Error("Error retrieving value from cache:", err) + } + time.Sleep(150 * time.Millisecond) // check key `1` again, it should still be alive since we just accessed it @@ -81,6 +88,12 @@ func TestCacheExpire(t *testing.T) { if err == nil { t.Error("Found key which should have been expired by now") } + + // check key `3`, it should have been removed by now + _, err = table.Value(k + "_3") + if err == nil { + t.Error("Found key which should have been expired by now") + } } func TestExists(t *testing.T) { diff --git a/cachetable.go b/cachetable.go index 1fa75ad..0fdf443 100644 --- a/cachetable.go +++ b/cachetable.go @@ -76,7 +76,7 @@ func (table *CacheTable) SetAddedItemCallback(f func(*CacheItem)) { table.addedItem = append(table.addedItem, f) } -//AddAddedItemCallback appends a new callback to the addedItem queue +// AddAddedItemCallback appends a new callback to the addedItem queue func (table *CacheTable) AddAddedItemCallback(f func(*CacheItem)) { table.Lock() defer table.Unlock() @@ -278,6 +278,16 @@ func (table *CacheTable) NotFoundAdd(key interface{}, lifeSpan time.Duration, da // Value returns an item from the cache and marks it to be kept alive. You can // pass additional arguments to your DataLoader callback function. func (table *CacheTable) Value(key interface{}, args ...interface{}) (*CacheItem, error) { + return table.valueInternal(key, true, args) +} + +// ValueOnly returns an item from the cache and does not mark it to be kept alive. You can +// pass additional arguments to your DataLoader callback function. +func (table *CacheTable) ValueOnly(key interface{}, args ...interface{}) (*CacheItem, error) { + return table.valueInternal(key, false, args) +} + +func (table *CacheTable) valueInternal(key interface{}, updateKeepAlive bool, args ...interface{}) (*CacheItem, error) { table.RLock() r, ok := table.items[key] loadData := table.loadData @@ -285,7 +295,9 @@ func (table *CacheTable) Value(key interface{}, args ...interface{}) (*CacheItem if ok { // Update access counter and timestamp. - r.KeepAlive() + if updateKeepAlive { + r.KeepAlive() + } return r, nil }