hugolib: Prevent parallel server rebuilds

There have been reports about infrequent paginator crashes when running the Hugo server since 0.55.0.

The reason have been narrowed down to that of parallel rebuilds.

This isn't a new thing, but the changes in 0.55.0 made it extra important to serialize the page initialization.

This commit fixes that by protecting the `Build` method with a lock when running in server mode.

Fixes #5885
Fixes #5968
This commit is contained in:
Bjørn Erik Pedersen 2019-05-18 08:38:58 +02:00
parent a83256b9cd
commit 95ce2a40e7
No known key found for this signature in database
GPG key ID: 330E6E2BD4859D8F
2 changed files with 9 additions and 0 deletions

View file

@ -62,6 +62,9 @@ type HugoSites struct {
// If this is running in the dev server. // If this is running in the dev server.
running bool running bool
// Serializes rebuilds when server is running.
runningMu sync.Mutex
// Render output formats for all sites. // Render output formats for all sites.
renderFormats output.Formats renderFormats output.Formats

View file

@ -31,6 +31,12 @@ import (
// Build builds all sites. If filesystem events are provided, // Build builds all sites. If filesystem events are provided,
// this is considered to be a potential partial rebuild. // this is considered to be a potential partial rebuild.
func (h *HugoSites) Build(config BuildCfg, events ...fsnotify.Event) error { func (h *HugoSites) Build(config BuildCfg, events ...fsnotify.Event) error {
if h.running {
// Make sure we don't trigger rebuilds in parallel.
h.runningMu.Lock()
defer h.runningMu.Unlock()
}
ctx, task := trace.NewTask(context.Background(), "Build") ctx, task := trace.NewTask(context.Background(), "Build")
defer task.End() defer task.End()