diff options
author | Bjørn Erik Pedersen <[email protected]> | 2024-02-02 11:20:08 +0100 |
---|---|---|
committer | Bjørn Erik Pedersen <[email protected]> | 2024-02-04 16:55:06 +0100 |
commit | 609d798e342c873143cf7ad05e987f3d8f7fbb45 (patch) | |
tree | a47532d5ba4acf3f12aad25791ee24ff802af35e /cache | |
parent | 53f204310ec8362d7084c123e8e16f5bb73dd257 (diff) | |
download | hugo-609d798e342c873143cf7ad05e987f3d8f7fbb45.tar.gz hugo-609d798e342c873143cf7ad05e987f3d8f7fbb45.zip |
Handle resource changes when the resources is already evicted from cache
Also fix a logical flaw in the cache resizer that made it too aggressive. After this I haven't been able to reproduce #11988, but I need to look closer.
Closes #11973
Updates #11988
Diffstat (limited to 'cache')
-rw-r--r-- | cache/dynacache/dynacache.go | 50 |
1 files changed, 41 insertions, 9 deletions
diff --git a/cache/dynacache/dynacache.go b/cache/dynacache/dynacache.go index bb3f7b098..85b360138 100644 --- a/cache/dynacache/dynacache.go +++ b/cache/dynacache/dynacache.go @@ -25,6 +25,7 @@ import ( "github.com/bep/lazycache" "github.com/bep/logg" + "github.com/gohugoio/hugo/common/collections" "github.com/gohugoio/hugo/common/herrors" "github.com/gohugoio/hugo/common/loggers" "github.com/gohugoio/hugo/common/paths" @@ -63,11 +64,26 @@ func New(opts Options) *Cache { infol := opts.Log.InfoCommand("dynacache") + evictedIdentities := collections.NewStack[identity.Identity]() + + onEvict := func(k, v any) { + if !opts.Running { + return + } + identity.WalkIdentitiesShallow(v, func(level int, id identity.Identity) bool { + evictedIdentities.Push(id) + return false + }) + resource.MarkStale(v) + } + c := &Cache{ - partitions: make(map[string]PartitionManager), - opts: opts, - stats: stats, - infol: infol, + partitions: make(map[string]PartitionManager), + onEvict: onEvict, + evictedIdentities: evictedIdentities, + opts: opts, + stats: stats, + infol: infol, } c.stop = c.start() @@ -106,14 +122,23 @@ type Cache struct { mu sync.RWMutex partitions map[string]PartitionManager - opts Options - infol logg.LevelLogger + + onEvict func(k, v any) + evictedIdentities *collections.Stack[identity.Identity] + + opts Options + infol logg.LevelLogger stats *stats stopOnce sync.Once stop func() } +// DrainEvictedIdentities drains the evicted identities from the cache. +func (c *Cache) DrainEvictedIdentities() []identity.Identity { + return c.evictedIdentities.Drain() +} + // ClearMatching clears all partition for which the predicate returns true. func (c *Cache) ClearMatching(predicate func(k, v any) bool) { g := rungroup.Run[PartitionManager](context.Background(), rungroup.Config[PartitionManager]{ @@ -318,9 +343,13 @@ func GetOrCreatePartition[K comparable, V any](c *Cache, name string, opts Optio const numberOfPartitionsEstimate = 10 maxSize := opts.CalculateMaxSize(c.opts.MaxSize / numberOfPartitionsEstimate) + onEvict := func(k K, v V) { + c.onEvict(k, v) + } + // Create a new partition and cache it. partition := &Partition[K, V]{ - c: lazycache.New(lazycache.Options[K, V]{MaxEntries: maxSize}), + c: lazycache.New(lazycache.Options[K, V]{MaxEntries: maxSize, OnEvict: onEvict}), maxSize: maxSize, trace: c.opts.Log.Logger().WithLevel(logg.LevelTrace).WithField("partition", name), opts: opts, @@ -445,7 +474,6 @@ func (p *Partition[K, V]) clearOnRebuild(changeset ...identity.Identity) { }, ), ) - resource.MarkStale(v) return true } return false @@ -483,6 +511,10 @@ func (p *Partition[K, V]) adjustMaxSize(newMaxSize int) int { if newMaxSize < minMaxSize { newMaxSize = minMaxSize } + oldMaxSize := p.maxSize + if newMaxSize == oldMaxSize { + return 0 + } p.maxSize = newMaxSize // fmt.Println("Adjusting max size of partition from", oldMaxSize, "to", newMaxSize) return p.c.Resize(newMaxSize) @@ -535,7 +567,7 @@ type stats struct { func (s *stats) adjustCurrentMaxSize() bool { newCurrentMaxSize := int(math.Floor(float64(s.opts.MaxSize) * s.adjustmentFactor)) - if newCurrentMaxSize < s.opts.MaxSize { + if newCurrentMaxSize < s.opts.MinMaxSize { newCurrentMaxSize = int(s.opts.MinMaxSize) } changed := newCurrentMaxSize != s.currentMaxSize |