go-cache icon indicating copy to clipboard operation
go-cache copied to clipboard

The OnEvicted function is not called if a value is re-set after expiration but before deletion

Open vic4hub opened this issue 7 years ago • 9 comments

Hello, in my testing, my simple function which prints integer counts for a key to be evicted (set via .OnEvicted) is not happening some of the time, despite eviction happening as expected. I am using GO 1.7

vic4hub avatar Feb 28 '17 15:02 vic4hub

Please provide an example of failing code.

patrickmn avatar Feb 28 '17 16:02 patrickmn

package main

import (
	"time"
	"log"
	"github.com/patrickmn/go-cache"
)

func main() {

	gc := cache.New(5 * time.Second, 3 * time.Second)
	gc.OnEvicted(func(k string, v interface{}) {
		log.Println("evicting key: ", k, " value: ", v.(int))
	})
	Write(gc)
	time.Sleep(1 * time.Hour)
}

func Write(gc *cache.Cache) {
	for i := 1; i <= 40; i++ {
		cnt , itemErr := gc.IncrementInt("key1", 1);
		if  itemErr != nil{
			println(itemErr.Error())
			gc.Set("key1", 1, 5 * time.Second)
		}else{
			log.Println(cnt)
		}
		time.Sleep(300 * time.Millisecond)
	}
}

vic4hub avatar Feb 28 '17 17:02 vic4hub

What exactly are you expecting to see, and what happens instead?

patrickmn avatar Feb 28 '17 17:02 patrickmn

When provided, it is expected for eviction function to run every time key:val pair is evicted - however, if you run my code, you will see it does not happen.

vic4hub avatar Feb 28 '17 17:02 vic4hub

This is because eviction happens during the cleanup, but the value is re-set after the item has expired and before the cleanup has run.

I agree this is a bug.

patrickmn avatar Feb 28 '17 17:02 patrickmn

I see where it happens, got to change increment/decrement logic from "if !found || v.Expired() {" to just "if !found" throughout

vic4hub avatar Feb 28 '17 18:02 vic4hub

You don't want to return values that have expired, though. Probably the fix is to check if a value exists but has expired in the Set functions, rather than just overwriting immediately (resulting in the evictor not seeing the old value and therefore not calling the OnExpired function on it.)

patrickmn avatar Feb 28 '17 20:02 patrickmn

@patrickmn any updates on getting this fixed?

jerrypeng avatar Dec 05 '19 19:12 jerrypeng

We made that fix https://github.com/patrickmn/go-cache/pull/132 for this issue :)

ayufan avatar Oct 14 '20 08:10 ayufan