ref: 6b6dcb44a014699c289bf32fe57d4c4216777be0
parent: d96f2a460f58e91d8f6253a489d4879acfec6916
author: Bjørn Erik Pedersen <[email protected]>
date: Wed Jul 11 15:23:22 EDT 2018
Flush partialCached cache on rebuilds Fixes #4931
--- a/deps/deps.go
+++ b/deps/deps.go
@@ -1,6 +1,7 @@
package deps
import (
+ "sync"
"time"
"github.com/gohugoio/hugo/common/loggers"
@@ -22,6 +23,7 @@
// There will be normally only one instance of deps in play
// at a given time, i.e. one per Site built.
type Deps struct {
+
// The logger to use.
Log *jww.Notepad `json:"-"`
@@ -69,8 +71,32 @@
// Timeout is configurable in site config.
Timeout time.Duration
+
+ // BuildStartListeners will be notified before a build starts.
+ BuildStartListeners *Listeners
}
+type Listeners struct {
+ sync.Mutex
+
+ // A list of funcs to be notified about an event.
+ listeners []func()
+}
+
+func (b *Listeners) Add(f func()) {
+ b.Lock()
+ defer b.Unlock()
+ b.listeners = append(b.listeners, f)
+}
+
+func (b *Listeners) Notify() {
+ b.Lock()
+ defer b.Unlock()
+ for _, notify := range b.listeners {
+ notify()
+ }
+}
+
// ResourceProvider is used to create and refresh, and clone resources needed.
type ResourceProvider interface {
Update(deps *Deps) error
@@ -168,6 +194,7 @@
ResourceSpec: resourceSpec,
Cfg: cfg.Language,
Language: cfg.Language,
+ BuildStartListeners: &Listeners{},
Timeout: time.Duration(timeoutms) * time.Millisecond,
}
@@ -209,6 +236,8 @@
if err := d.templateProvider.Clone(&d); err != nil {
return nil, err
}
+
+ d.BuildStartListeners = &Listeners{}
return &d, nil
--- a/hugolib/hugo_sites_build.go
+++ b/hugolib/hugo_sites_build.go
@@ -28,6 +28,7 @@
// Build builds all sites. If filesystem events are provided,
// this is considered to be a potential partial rebuild.
func (h *HugoSites) Build(config BuildCfg, events ...fsnotify.Event) error {
+
if h.Metrics != nil {
h.Metrics.Reset()
}
@@ -40,6 +41,10 @@
if conf.whatChanged == nil {
// Assume everything has changed
conf.whatChanged = &whatChanged{source: true, other: true}
+ }
+
+ for _, s := range h.Sites {
+ s.Deps.BuildStartListeners.Notify()
}
if len(events) > 0 {
--- a/tpl/partials/init_test.go
+++ b/tpl/partials/init_test.go
@@ -26,7 +26,9 @@
var ns *internal.TemplateFuncsNamespace
for _, nsf := range internal.TemplateFuncsNamespaceRegistry {
- ns = nsf(&deps.Deps{})
+ ns = nsf(&deps.Deps{
+ BuildStartListeners: &deps.Listeners{},
+ })
if ns.Name == name {
found = true
break
--- a/tpl/partials/partials.go
+++ b/tpl/partials/partials.go
@@ -34,11 +34,23 @@
p map[string]interface{}
}
+func (p *partialCache) clear() {
+ p.Lock()
+ defer p.Unlock()
+ p.p = make(map[string]interface{})
+}
+
// New returns a new instance of the templates-namespaced template functions.
func New(deps *deps.Deps) *Namespace {
+ cache := &partialCache{p: make(map[string]interface{})}
+ deps.BuildStartListeners.Add(
+ func() {
+ cache.clear()
+ })
+
return &Namespace{
deps: deps,
- cachedPartials: partialCache{p: make(map[string]interface{})},
+ cachedPartials: cache,
}
}
@@ -45,7 +57,7 @@
// Namespace provides template functions for the "templates" namespace.
type Namespace struct {
deps *deps.Deps
- cachedPartials partialCache
+ cachedPartials *partialCache
}
// Include executes the named partial and returns either a string,