Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 21 additions & 11 deletions lazycache.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package lazycache

import (
"fmt"
"sync"

"github.com/hashicorp/golang-lru/v2/simplelru"
Expand Down Expand Up @@ -121,19 +122,28 @@ func (c *Cache[K, V]) GetOrCreate(key K, create func(key K) (V, error)) (V, bool
c.lru.Add(key, w)
c.mu.Unlock()

// Create the value with the lock released.
v, err := create(key)
w.err = err
w.value = v
w.found = err == nil
v, err := func() (v V, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic: %v", r)
}
w.err = err
w.value = v
w.found = err == nil
close(w.ready)

if err != nil {
v = c.zerov
c.Delete(key)
}
}()
// Create the value with the lock released.
v, err = create(key)

close(w.ready)
return
}()

if err != nil {
c.Delete(key)
return c.zerov, false, err
}
return v, false, nil
return v, false, err
}

// Resize changes the cache size and returns the number of entries evicted.
Expand Down
18 changes: 18 additions & 0 deletions lazycache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,24 @@ func TestCache(t *testing.T) {
c.Assert(func() { New[int, any](Options[int, any]{MaxEntries: -1}) }, qt.PanicMatches, "must provide a positive size")
}

func TestPanic(t *testing.T) {
c := qt.New(t)

cache := New(Options[int, any]{MaxEntries: 1000})
for i := 0; i < 2; i++ {
_, _, err := cache.GetOrCreate(42, func(key int) (any, error) {
panic("failed1")
})
c.Assert(err, qt.IsNotNil)
c.Assert(err, qt.ErrorMatches, "panic: failed1")
_, _, err = cache.GetOrCreate(i, func(key int) (any, error) {
panic("failed2")
})
c.Assert(err, qt.IsNotNil)
c.Assert(err, qt.ErrorMatches, "panic: failed2")
}
}

func TestDeleteFunc(t *testing.T) {
c := qt.New(t)

Expand Down
Loading