ref: 4a366fcfee24b3a5a5045b16c3b87b76147adf5e
parent: 083311d0336ced35909b3375950f7817ecf95ed0
author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
date: Wed Oct 17 05:28:04 EDT 2018
Prevent stale content in Fast Render Mode We do that by re-render visited pages that is not already in the stack. This may potentially do some double work, but that small penalty should be well worth it. Fixes #5281
--- a/commands/commandeer.go
+++ b/commands/commandeer.go
@@ -324,10 +324,7 @@
fs.Destination = new(afero.MemMapFs)
}
- doLiveReload := !c.h.buildWatch && !config.GetBool("disableLiveReload")- fastRenderMode := doLiveReload && !config.GetBool("disableFastRender")-
- if fastRenderMode {+ if c.fastRenderMode {// For now, fast render mode only. It should, however, be fast enough
// for the full variant, too.
changeDetector := &fileChangeDetector{--- a/commands/hugo.go
+++ b/commands/hugo.go
@@ -618,13 +618,20 @@
return c.hugo.Build(hugolib.BuildCfg{})}
+func (c *commandeer) handleBuildErr(err error, msg string) {+ c.buildErr = err
+ c.logger.ERROR.Printf("%s: %s", msg, err)+ if !c.h.quiet && c.h.verbose {+ herrors.PrintStackTrace(err)
+ }
+}
+
func (c *commandeer) rebuildSites(events []fsnotify.Event) error {defer c.timeTrack(time.Now(), "Total")
c.buildErr = nil
visited := c.visitedURLs.PeekAllSet()
- doLiveReload := !c.h.buildWatch && !c.Cfg.GetBool("disableLiveReload")- if doLiveReload && !c.Cfg.GetBool("disableFastRender") {+ if c.fastRenderMode {// Make sure we always render the home pages
for _, l := range c.languages {@@ -640,6 +647,15 @@
return c.hugo.Build(hugolib.BuildCfg{RecentlyVisited: visited}, events...)}
+func (c *commandeer) partialReRender(urls ...string) error {+ c.buildErr = nil
+ visited := make(map[string]bool)
+ for _, url := range urls {+ visited[url] = true
+ }
+ return c.hugo.Build(hugolib.BuildCfg{RecentlyVisited: visited, PartialReRender: true})+}
+
func (c *commandeer) fullRebuild() { c.commandeerHugoState = &commandeerHugoState{}err := c.loadConfig(true, true)
@@ -907,15 +923,10 @@
c.changeDetector.PrepareNew()
if err := c.rebuildSites(dynamicEvents); err != nil {- c.buildErr = err
- c.logger.ERROR.Printf("Rebuild failed: %s", err)- if !c.h.quiet && c.h.verbose {- herrors.PrintStackTrace(err)
- }
+ c.handleBuildErr(err, "Rebuild failed")
}
if doLiveReload {-
if len(partitionedEvents.ContentEvents) == 0 && len(partitionedEvents.AssetEvents) > 0 {changed := c.changeDetector.changed()
if c.changeDetector != nil && len(changed) == 0 {--- a/commands/server.go
+++ b/commands/server.go
@@ -345,10 +345,22 @@
w.Header().Set("Pragma", "no-cache")}
- if f.c.fastRenderMode {+ if f.c.fastRenderMode && f.c.buildErr == nil {p := r.RequestURI
if strings.HasSuffix(p, "/") || strings.HasSuffix(p, "html") || strings.HasSuffix(p, "htm") {+ if !f.c.visitedURLs.Contains(p) {+ // If not already on stack, re-render that single page.
+ if err := f.c.partialReRender(p); err != nil {+ f.c.handleBuildErr(err, fmt.Sprintf("Failed to render %q", p))+ if f.c.showErrorInBrowser {+ http.Redirect(w, r, p, 301)
+ return
+ }
+ }
+ }
+
f.c.visitedURLs.Add(p)
+
}
}
h.ServeHTTP(w, r)
--- a/common/types/evictingqueue.go
+++ b/common/types/evictingqueue.go
@@ -52,6 +52,13 @@
q.mu.Unlock()
}
+// Contains returns whether the queue contains v.
+func (q *EvictingStringQueue) Contains(v string) bool {+ q.mu.Lock()
+ defer q.mu.Unlock()
+ return q.set[v]
+}
+
// Peek looks at the last element added to the queue.
func (q *EvictingStringQueue) Peek() string {q.mu.Lock()
--- a/common/types/evictingqueue_test.go
+++ b/common/types/evictingqueue_test.go
@@ -36,6 +36,9 @@
queue.Add("a") queue.Add("b")+ assert.True(queue.Contains("a"))+ assert.False(queue.Contains("foo"))+
assert.Equal([]string{"b", "a"}, queue.PeekAll()) assert.Equal("b", queue.Peek()) queue.Add("c")--- a/hugolib/hugo_sites.go
+++ b/hugolib/hugo_sites.go
@@ -368,6 +368,11 @@
SkipRender bool
// Use this to indicate what changed (for rebuilds).
whatChanged *whatChanged
+
+ // This is a partial re-render of some selected pages. This means
+ // we should skip most of the processing.
+ PartialReRender bool
+
// Recently visited URLs. This is used for partial re-rendering.
RecentlyVisited map[string]bool
}
--- a/hugolib/hugo_sites_build.go
+++ b/hugolib/hugo_sites_build.go
@@ -41,29 +41,31 @@
conf.whatChanged = &whatChanged{source: true, other: true}}
- for _, s := range h.Sites {- s.Deps.BuildStartListeners.Notify()
- }
+ if !config.PartialReRender {+ for _, s := range h.Sites {+ s.Deps.BuildStartListeners.Notify()
+ }
- if len(events) > 0 {- // Rebuild
- if err := h.initRebuild(conf); err != nil {+ if len(events) > 0 {+ // Rebuild
+ if err := h.initRebuild(conf); err != nil {+ return err
+ }
+ } else {+ if err := h.init(conf); err != nil {+ return err
+ }
+ }
+
+ if err := h.process(conf, events...); err != nil {return err
}
- } else {- if err := h.init(conf); err != nil {+
+ if err := h.assemble(conf); err != nil {return err
}
}
- if err := h.process(conf, events...); err != nil {- return err
- }
-
- if err := h.assemble(conf); err != nil {- return err
- }
-
if err := h.render(conf); err != nil {return err
}
@@ -226,8 +228,10 @@
}
func (h *HugoSites) render(config *BuildCfg) error {- for _, s := range h.Sites {- s.initRenderFormats()
+ if !config.PartialReRender {+ for _, s := range h.Sites {+ s.initRenderFormats()
+ }
}
for _, s := range h.Sites {@@ -240,15 +244,23 @@
isRenderingSite := s == s2
- if err := s2.preparePagesForRender(isRenderingSite && i == 0); err != nil {- return err
+ if !config.PartialReRender {+ if err := s2.preparePagesForRender(isRenderingSite && i == 0); err != nil {+ return err
+ }
}
}
if !config.SkipRender {- if err := s.render(config, i); err != nil {- return err
+ if config.PartialReRender {+ if err := s.renderPages(config); err != nil {+ return err
+ }
+ } else {+ if err := s.render(config, i); err != nil {+ return err
+ }
}
}
}
--- a/hugolib/site_render.go
+++ b/hugolib/site_render.go
@@ -43,7 +43,7 @@
go pageRenderer(s, pages, results, wg)
}
- if len(s.headlessPages) > 0 {+ if !cfg.PartialReRender && len(s.headlessPages) > 0 {wg.Add(1)
go headlessPagesPublisher(s, wg)
}
--
⑨