aboutsummaryrefslogtreecommitdiffhomepage
path: root/cache
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <[email protected]>2024-10-27 10:31:59 +0100
committerBjørn Erik Pedersen <[email protected]>2024-10-27 12:43:36 +0100
commit62567d38205a61134a6822d37a534520772419f1 (patch)
treef2b2268634a9b778180e8811414ac4b95c460c05 /cache
parente10915f80af18cbe24b0f5e22922b87ce0bc74ae (diff)
downloadhugo-62567d38205a61134a6822d37a534520772419f1.tar.gz
hugo-62567d38205a61134a6822d37a534520772419f1.zip
deps: Upgrade github.com/bep/lazycache v0.6.0 => v0.7.0
Diffstat (limited to 'cache')
-rw-r--r--cache/dynacache/dynacache.go25
-rw-r--r--cache/dynacache/dynacache_test.go44
2 files changed, 56 insertions, 13 deletions
diff --git a/cache/dynacache/dynacache.go b/cache/dynacache/dynacache.go
index 5007e27ba..a906a0dd3 100644
--- a/cache/dynacache/dynacache.go
+++ b/cache/dynacache/dynacache.go
@@ -430,12 +430,25 @@ func (p *Partition[K, V]) doGetOrCreateWitTimeout(key K, duration time.Duration,
errch := make(chan error, 1)
go func() {
- v, _, err := p.c.GetOrCreate(key, create)
- if err != nil {
- errch <- err
- return
- }
- resultch <- v
+ var (
+ v V
+ err error
+ )
+ defer func() {
+ if r := recover(); r != nil {
+ if rerr, ok := r.(error); ok {
+ err = rerr
+ } else {
+ err = fmt.Errorf("panic: %v", r)
+ }
+ }
+ if err != nil {
+ errch <- err
+ } else {
+ resultch <- v
+ }
+ }()
+ v, _, err = p.c.GetOrCreate(key, create)
}()
select {
diff --git a/cache/dynacache/dynacache_test.go b/cache/dynacache/dynacache_test.go
index 9a932729b..87239479b 100644
--- a/cache/dynacache/dynacache_test.go
+++ b/cache/dynacache/dynacache_test.go
@@ -14,6 +14,7 @@
package dynacache
import (
+ "errors"
"fmt"
"path/filepath"
"testing"
@@ -174,18 +175,47 @@ func TestPanicInCreate(t *testing.T) {
p1 := GetOrCreatePartition[string, testItem](cache, "/aaaa/bbbb", OptionsPartition{Weight: 30, ClearWhen: ClearOnRebuild})
+ willPanic := func(i int) func() {
+ return func() {
+ p1.GetOrCreate(fmt.Sprintf("panic-%d", i), func(key string) (testItem, error) {
+ panic(errors.New(key))
+ })
+ }
+ }
+
+ // GetOrCreateWitTimeout needs to recover from panics in the create func.
+ willErr := func(i int) error {
+ _, err := p1.GetOrCreateWitTimeout(fmt.Sprintf("error-%d", i), 10*time.Second, func(key string) (testItem, error) {
+ return testItem{}, errors.New(key)
+ })
+ return err
+ }
+
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
- _, err := p1.GetOrCreate(fmt.Sprintf("panic1-%d", i), func(string) (testItem, error) {
- panic("failed")
- })
+ c.Assert(willPanic(i), qt.PanicMatches, fmt.Sprintf("panic-%d", i))
+ c.Assert(willErr(i), qt.ErrorMatches, fmt.Sprintf("error-%d", i))
+ }
+ }
- c.Assert(err, qt.Not(qt.IsNil))
+ // Test the same keys again without the panic.
+ for i := 0; i < 3; i++ {
+ for j := 0; j < 3; j++ {
+ v, err := p1.GetOrCreate(fmt.Sprintf("panic-%d", i), func(key string) (testItem, error) {
+ return testItem{
+ name: key,
+ }, nil
+ })
+ c.Assert(err, qt.IsNil)
+ c.Assert(v.name, qt.Equals, fmt.Sprintf("panic-%d", i))
- _, err = p1.GetOrCreateWitTimeout(fmt.Sprintf("panic2-%d", i), 10*time.Second, func(string) (testItem, error) {
- panic("failed")
+ v, err = p1.GetOrCreateWitTimeout(fmt.Sprintf("error-%d", i), 10*time.Second, func(key string) (testItem, error) {
+ return testItem{
+ name: key,
+ }, nil
})
- c.Assert(err, qt.Not(qt.IsNil))
+ c.Assert(err, qt.IsNil)
+ c.Assert(v.name, qt.Equals, fmt.Sprintf("error-%d", i))
}
}
}