bigcache icon indicating copy to clipboard operation
bigcache copied to clipboard

What happens when I set CleanWindow = 0 ? No cache will be cleared but will LifeWindow entries...

Open hiqsociety opened this issue 4 years ago • 10 comments
trafficstars

What happens when I set CleanWindow = 0 ? No cache will be cleared but will LifeWindow entries be able to Get?

Is CleanWindow a bit redundant? it's ok to leave expired entries in LifeWindow right? It just sits there and will not be gotten out.

hiqsociety avatar Mar 18 '21 00:03 hiqsociety

You are partially correct. Setting clean window to 0 will disable periodical house keeping – removing expired entries. Theses entries could be removed when space is needed to insert new value.

It might look redundant but there was a valid use case for it https://github.com/allegro/bigcache/issues/31#issuecomment-678782411

janisz avatar Mar 22 '21 18:03 janisz

would be great if the doc on the LifeWindow could be more clear

Here is my current setting:

		// time after which entry can be evicted
		// Set to infinity.
		LifeWindow: time.Duration(math.MaxInt32) * time.Second,

		// Interval between removing expired entries (clean up).
		// If set to <= 0 then no action is performed.
		// Setting to < 1 second is counterproductive — bigcache has a one second resolution.
		CleanWindow: 0,

Issue:

Our desire is to have a forever in memory cache, with random failure, we happens to find that even clean window to 0, the item can be deleted.

And, this code made me very confusing: https://github.com/allegro/bigcache/blob/master/bigcache.go#L101

after verified with below test case, easy to catch:

--- FAIL: Test_BigCache_Lifewindow (1.03s)
    logger.go:130: 2022-12-02T23:58:58.002Z	ERROR	Cache Instance OnRemoveWithReason	{"Key": "test1", "Entry": "dGVzdC12YWx1ZS0x", "Reason": 1}
    key_cache_test.go:51:
        	Error Trace:	xxxxxxx key_cache_test.go:51
        	Error:      	Received unexpected error:
        	            	Entry not found
        	Test:       	Test_BigCache_Lifewindow

Test Code

package mytest

import (
	"strconv"
	"testing"
	"time"

	"go.uber.org/zap"
	"go.uber.org/zap/zaptest"

	"github.com/allegro/bigcache/v3"
	"github.com/stretchr/testify/require"
)

// This test was designed to verify when set cleanwindow to 0, what will happen if lifewindow expires.
// refer: https: //github.com/allegro/bigcache/issues/273
func Test_BigCache_Lifewindow(t *testing.T) {
	l := zaptest.NewLogger(t, zaptest.Level(zap.DebugLevel))
	onRemoveWithReason := func(key string, entry []byte, reason bigcache.RemoveReason) {
		l.Error("Cache Instance OnRemoveWithReason",
			zap.String("Key", key),
			zap.Reflect("Entry", entry),
			zap.Reflect("Reason", reason))
	}

	testConfig := bigcache.Config{
		Shards: 2,
		// time after which entry can be evicted
		// Set to infinity.
		LifeWindow: 1 * time.Second,
		// Interval between removing expired entries (clean up).
		// If set to <= 0 then no action is performed.
		// Setting to < 1 second is counterproductive — bigcache has a one second resolution.
		CleanWindow:        0,
		OnRemoveWithReason: onRemoveWithReason,
	}
	cacheInstance, err := bigcache.NewBigCache(testConfig)
	require.NoError(t, err)
	pk := "test1"
	value := []byte("test-value-1")
	require.NoError(t, cacheInstance.Set(pk, value))

	for i := 0; i < 500; i++ {
		getV, err := cacheInstance.Get(pk)
		require.NoError(t, err)
		// refer: https://github.com/allegro/bigcache/issues/31
		require.NoError(t, cacheInstance.Set("key"+strconv.Itoa(i), []byte("test")))
		require.Equal(t, string(value), string(getV))
		time.Sleep(10 * time.Millisecond)
	}
}

hixichen avatar Dec 05 '22 21:12 hixichen

we happens to find that even clean window to 0, the item can be deleted.

It's not deleted but evicted. https://github.com/allegro/bigcache/blob/0b306aa0178fd90ba15e23da9bbba6dee71af1d6/bigcache.go#L34-L35

Have you tried reading it with https://github.com/allegro/bigcache/blob/982ec3b09cacb9936b88dcfdaed329870065cf23/bigcache.go#L139-L146

janisz avatar Dec 06 '22 13:12 janisz

I'm running into the same problem. I'm looking to have a forever in-memory cache, but keys are getting removed even when Life window, Clean window and Hard max cache size are set to 0, 0 and 0 respectively. How do I go about this?

SwarnaLathaNatarajan avatar May 17 '23 20:05 SwarnaLathaNatarajan

Have you tired to set life window to max int?

janisz avatar May 17 '23 20:05 janisz

yes, that resolves the issue. Would this guarantee a forever in-memory cache?

SwarnaLathaNatarajan avatar May 17 '23 21:05 SwarnaLathaNatarajan

I'd say yes but I think we should add more explicit way of saying that entries should never expire. Maybe new config option or treat -1 as never expire and then handle it differently in shard https://github.com/allegro/bigcache/blob/982ec3b09cacb9936b88dcfdaed329870065cf23/shard.go#L284-L289

janisz avatar May 18 '23 08:05 janisz

yea that would be very helpful. Thanks for the help.

Also, I noticed that the keys were being removed only sometimes when Life window, Clean window and Hard max cache size were set to 0, 0 and 0 respectively. Why was that not consistent?

SwarnaLathaNatarajan avatar May 18 '23 13:05 SwarnaLathaNatarajan

That's interesting? Are you sure it was how could it be reproduced?

janisz avatar May 18 '23 14:05 janisz

yes, I executed the same code both locally and on a remote instance. The local cache worked, but the remote one ran into the key removal issue and this was consistent.

SwarnaLathaNatarajan avatar May 18 '23 14:05 SwarnaLathaNatarajan