cache: fix a bug with Prepopulate

Prepopulate was setting entry.Expiry.HeapIndex to 0. Previously this would result in a call to heap.Fix(0)
which wasn't correct, but was also not really a problem because at worse it would re-notify.

With the recent change to extract cachettl it was changed to call Update(idx), which would have updated
the wrong entry.

A previous commit removed the setting of entry.Expiry so that the HeapIndex would be reported
as -1, and this commit adds a test and handles the -1 heap index.
This commit is contained in:
Daniel Nephin 2020-10-20 18:58:30 -04:00
parent 9d5b738cdb
commit 0beaced90f
2 changed files with 50 additions and 0 deletions

View File

@ -1430,3 +1430,49 @@ func TestCache_ExpiryLoop_ExitsWhenStopped(t *testing.T) {
t.Fatalf("expected loop to exit when stopped") t.Fatalf("expected loop to exit when stopped")
} }
} }
func TestCache_Prepopulate(t *testing.T) {
typ := &fakeType{index: 5}
c := New(Options{})
c.RegisterType("t", typ)
c.Prepopulate("t", FetchResult{Value: 17, Index: 1}, "dc1", "token", "v1")
ctx := context.Background()
req := fakeRequest{
info: RequestInfo{
Key: "v1",
Token: "token",
Datacenter: "dc1",
MinIndex: 1,
},
}
result, _, err := c.Get(ctx, "t", req)
require.NoError(t, err)
require.Equal(t, 17, result)
}
type fakeType struct {
index uint64
}
func (f fakeType) Fetch(_ FetchOptions, _ Request) (FetchResult, error) {
idx := atomic.LoadUint64(&f.index)
return FetchResult{Value: int(idx * 2), Index: idx}, nil
}
func (f fakeType) RegisterOptions() RegisterOptions {
return RegisterOptions{Refresh: true}
}
var _ Type = (*fakeType)(nil)
type fakeRequest struct {
info RequestInfo
}
func (f fakeRequest) CacheInfo() RequestInfo {
return f.info
}
var _ Request = (*fakeRequest)(nil)

View File

@ -66,6 +66,10 @@ func (h *ExpiryHeap) Add(key string, expiry time.Duration) *Entry {
// //
// Must be synchronized by the caller. // Must be synchronized by the caller.
func (h *ExpiryHeap) Update(idx int, expiry time.Duration) { func (h *ExpiryHeap) Update(idx int, expiry time.Duration) {
if idx < 0 {
// the previous entry did not have a valid index, its not in the heap
return
}
entry := h.entries[idx] entry := h.entries[idx]
entry.expiry = time.Now().Add(expiry) entry.expiry = time.Now().Add(expiry)
heap.Fix((*entryHeap)(h), idx) heap.Fix((*entryHeap)(h), idx)