aboutsummaryrefslogtreecommitdiffhomepage
path: root/resources
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <[email protected]>2024-05-03 11:04:57 +0200
committerBjørn Erik Pedersen <[email protected]>2024-05-04 19:45:43 +0200
commit503d20954f10507b9b43c6ee1c38001e53cf0b14 (patch)
tree06e1aeddd995c2b8ff2fb48c0879187b2b819e4b /resources
parent68e95327f7be941c44c256d2dac74ea96e731674 (diff)
downloadhugo-503d20954f10507b9b43c6ee1c38001e53cf0b14.tar.gz
hugo-503d20954f10507b9b43c6ee1c38001e53cf0b14.zip
Make the cache eviction logic for stale entities more robust
Fixes #12458
Diffstat (limited to 'resources')
-rw-r--r--resources/resource.go17
-rw-r--r--resources/resource/resourcetypes.go24
-rw-r--r--resources/transform.go5
3 files changed, 30 insertions, 16 deletions
diff --git a/resources/resource.go b/resources/resource.go
index 867b262fb..0fee69cdd 100644
--- a/resources/resource.go
+++ b/resources/resource.go
@@ -296,16 +296,19 @@ type hashProvider interface {
hash() string
}
+var _ resource.StaleInfo = (*StaleValue[any])(nil)
+
type StaleValue[V any] struct {
// The value.
Value V
- // IsStaleFunc reports whether the value is stale.
- IsStaleFunc func() bool
+ // StaleVersionFunc reports the current version of the value.
+ // This always starts out at 0 and get incremented on staleness.
+ StaleVersionFunc func() uint32
}
-func (s *StaleValue[V]) IsStale() bool {
- return s.IsStaleFunc()
+func (s *StaleValue[V]) StaleVersion() uint32 {
+ return s.StaleVersionFunc()
}
type AtomicStaler struct {
@@ -313,11 +316,11 @@ type AtomicStaler struct {
}
func (s *AtomicStaler) MarkStale() {
- atomic.StoreUint32(&s.stale, 1)
+ atomic.AddUint32(&s.stale, 1)
}
-func (s *AtomicStaler) IsStale() bool {
- return atomic.LoadUint32(&(s.stale)) > 0
+func (s *AtomicStaler) StaleVersion() uint32 {
+ return atomic.LoadUint32(&(s.stale))
}
// For internal use.
diff --git a/resources/resource/resourcetypes.go b/resources/resource/resourcetypes.go
index 0766fe232..5d9533223 100644
--- a/resources/resource/resourcetypes.go
+++ b/resources/resource/resourcetypes.go
@@ -233,17 +233,27 @@ type StaleMarker interface {
// StaleInfo tells if a resource is marked as stale.
type StaleInfo interface {
- IsStale() bool
+ StaleVersion() uint32
}
-// IsStaleAny reports whether any of the os is marked as stale.
-func IsStaleAny(os ...any) bool {
- for _, o := range os {
- if s, ok := o.(StaleInfo); ok && s.IsStale() {
- return true
+// StaleVersion returns the StaleVersion for the given os,
+// or 0 if not set.
+func StaleVersion(os any) uint32 {
+ if s, ok := os.(StaleInfo); ok {
+ return s.StaleVersion()
+ }
+ return 0
+}
+
+// StaleVersionSum calculates the sum of the StaleVersionSum for the given oss.
+func StaleVersionSum(oss ...any) uint32 {
+ var version uint32
+ for _, o := range oss {
+ if s, ok := o.(StaleInfo); ok && s.StaleVersion() > 0 {
+ version += s.StaleVersion()
}
}
- return false
+ return version
}
// MarkStale will mark any of the oses as stale, if possible.
diff --git a/resources/transform.go b/resources/transform.go
index d9084b178..b498924f5 100644
--- a/resources/transform.go
+++ b/resources/transform.go
@@ -657,8 +657,9 @@ type resourceAdapterInner struct {
*publishOnce
}
-func (r *resourceAdapterInner) IsStale() bool {
- return r.Staler.IsStale() || r.target.IsStale()
+func (r *resourceAdapterInner) StaleVersion() uint32 {
+ // Both of these are incremented on change.
+ return r.Staler.StaleVersion() + r.target.StaleVersion()
}
type resourceTransformations struct {