summaryrefslogtreecommitdiffstats
path: root/hugolib/filesystems
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2021-10-17 11:54:55 +0200
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2021-10-18 12:13:13 +0200
commitba35e69856900b6fc92681aa841cdcaefbb4b121 (patch)
treeb9ffc699a99b2d6d947e1d53c383a1352ce93980 /hugolib/filesystems
parentc7957c90e83ff2b2cc958bd61486a244f0fd8891 (diff)
Add a cross process build lock and use it in the archetype content builder
Fixes #9048
Diffstat (limited to 'hugolib/filesystems')
-rw-r--r--hugolib/filesystems/basefs.go26
1 files changed, 26 insertions, 0 deletions
diff --git a/hugolib/filesystems/basefs.go b/hugolib/filesystems/basefs.go
index dcfee34ff..0a2c31240 100644
--- a/hugolib/filesystems/basefs.go
+++ b/hugolib/filesystems/basefs.go
@@ -24,7 +24,10 @@ import (
"strings"
"sync"
+ "github.com/gohugoio/hugo/htesting"
+
"github.com/gohugoio/hugo/common/loggers"
+ "github.com/rogpeppe/go-internal/lockedfile"
"github.com/gohugoio/hugo/hugofs/files"
@@ -38,6 +41,13 @@ import (
"github.com/spf13/afero"
)
+const (
+ // Used to control concurrency between multiple Hugo instances, e.g.
+ // a running server and building new content with 'hugo new'.
+ // It's placed in the project root.
+ lockFileBuild = ".hugo_build.lock"
+)
+
var filePathSeparator = string(filepath.Separator)
// BaseFs contains the core base filesystems used by Hugo. The name "base" is used
@@ -56,6 +66,21 @@ type BaseFs struct {
PublishFs afero.Fs
theBigFs *filesystemsCollector
+
+ // Locks.
+ buildMu *lockedfile.Mutex // <project>/.hugo_build.lock
+ buildMuTests sync.Mutex // Used in tests.
+}
+
+// Tries to acquire a build lock.
+func (fs *BaseFs) LockBuild() (unlock func(), err error) {
+ if htesting.IsTest {
+ fs.buildMuTests.Lock()
+ return func() {
+ fs.buildMuTests.Unlock()
+ }, nil
+ }
+ return fs.buildMu.Lock()
}
// TODO(bep) we can get regular files in here and that is fine, but
@@ -402,6 +427,7 @@ func NewBase(p *paths.Paths, logger loggers.Logger, options ...func(*BaseFs) err
b := &BaseFs{
SourceFs: sourceFs,
PublishFs: publishFs,
+ buildMu: lockedfile.MutexAt(filepath.Join(p.WorkingDir, lockFileBuild)),
}
for _, opt := range options {