summaryrefslogtreecommitdiffstats
path: root/hugolib
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2019-11-25 12:49:04 +0100
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2019-11-25 18:59:06 +0100
commitd6f7a9e28dfd5abff08b6aaf6fb3493c46bd1e39 (patch)
treef5715b86cff28eb5c7ab7320c30a492806441cae /hugolib
parent031f948f87ac97ca49d0a487a392a8a0c6afb699 (diff)
resources/images: Make the image cache more robust
Also allow timeout to be set as a duration string, e.g. `30s`. Fixes #6501
Diffstat (limited to 'hugolib')
-rw-r--r--hugolib/config.go2
-rw-r--r--hugolib/image_test.go46
-rw-r--r--hugolib/page__per_output.go8
-rw-r--r--hugolib/site.go18
4 files changed, 59 insertions, 15 deletions
diff --git a/hugolib/config.go b/hugolib/config.go
index 1bed9c0d9..e29d6ac9f 100644
--- a/hugolib/config.go
+++ b/hugolib/config.go
@@ -620,7 +620,7 @@ func loadDefaultSettingsFor(v *viper.Viper) error {
v.SetDefault("disableAliases", false)
v.SetDefault("debug", false)
v.SetDefault("disableFastRender", false)
- v.SetDefault("timeout", 30000) // 30 seconds
+ v.SetDefault("timeout", "30s")
v.SetDefault("enableInlineShortcodes", false)
return nil
diff --git a/hugolib/image_test.go b/hugolib/image_test.go
index d0bff75a2..bcd715f5c 100644
--- a/hugolib/image_test.go
+++ b/hugolib/image_test.go
@@ -35,11 +35,12 @@ func TestImageOps(t *testing.T) {
c.Assert(err, qt.IsNil)
defer clean()
- newBuilder := func() *sitesBuilder {
+ newBuilder := func(timeout string) *sitesBuilder {
v := viper.New()
v.Set("workingDir", workDir)
v.Set("baseURL", "https://example.org")
+ v.Set("timeout", timeout)
b := newTestSitesBuilder(t).WithWorkingDir(workDir)
b.Fs = hugofs.NewDefault(v)
@@ -49,9 +50,17 @@ func TestImageOps(t *testing.T) {
title: "My bundle"
---
+{{< imgproc >}}
+
`)
- b.WithTemplatesAdded("index.html", `
+ b.WithTemplatesAdded(
+ "shortcodes/imgproc.html", `
+{{ $img := resources.Get "images/sunset.jpg" }}
+{{ $r := $img.Resize "129x239" }}
+IMG SHORTCODE: {{ $r.RelPermalink }}/{{ $r.Width }}
+`,
+ "index.html", `
{{ $p := .Site.GetPage "mybundle" }}
{{ $img1 := resources.Get "images/sunset.jpg" }}
{{ $img2 := $p.Resources.GetMatch "sunset.jpg" }}
@@ -83,7 +92,7 @@ BG3: {{ $blurryGrayscale3.RelPermalink }}/{{ $blurryGrayscale3.Width }}
{{ $blurryGrayscale4 := $r.Filter $filters }}
BG4: {{ $blurryGrayscale4.RelPermalink }}/{{ $blurryGrayscale4.Width }}
-
+{{ $p.Content }}
`)
@@ -112,8 +121,8 @@ BG4: {{ $blurryGrayscale4.RelPermalink }}/{{ $blurryGrayscale4.Width }}
out.Close()
src.Close()
- b := newBuilder()
- b.Build(BuildCfg{})
+ // First build it with a very short timeout to trigger errors.
+ b := newBuilder("10ns")
imgExpect := `
Resized1: images/sunset.jpg|123|234|image/jpg|/images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_123x234_resize_q75_box.jpg|
@@ -126,16 +135,35 @@ BG1: /images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_2ae8bb993431ec1aec4
BG2: /images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_2ae8bb993431ec1aec40fe59927b46b4.jpg/123
BG3: /images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_ed7740a90b82802261c2fbdb98bc8082.jpg/123
BG4: /images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_ed7740a90b82802261c2fbdb98bc8082.jpg/123
+IMG SHORTCODE: /images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_129x239_resize_q75_box.jpg/129
`
- b.AssertFileContent(filepath.Join(workDir, "public/index.html"), imgExpect)
- b.AssertImage(350, 219, "public/images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_350x0_resize_q75_box.a86fe88d894e5db613f6aa8a80538fefc25b20fa24ba0d782c057adcef616f56.jpg")
+ assertImages := func() {
+ b.Helper()
+ b.AssertFileContent(filepath.Join(workDir, "public/index.html"), imgExpect)
+ b.AssertImage(350, 219, "public/images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_350x0_resize_q75_box.a86fe88d894e5db613f6aa8a80538fefc25b20fa24ba0d782c057adcef616f56.jpg")
+ b.AssertImage(129, 239, "public/images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_129x239_resize_q75_box.jpg")
+ }
+
+ err = b.BuildE(BuildCfg{})
+ c.Assert(err, qt.Not(qt.IsNil))
+
+ b = newBuilder("30s")
+ b.Build(BuildCfg{})
+
+ assertImages()
+
+ // Truncate one image.
+ imgInCache := filepath.Join(workDir, "resources/_gen/images/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_ed7740a90b82802261c2fbdb98bc8082.jpg")
+ f, err := os.Create(imgInCache)
+ c.Assert(err, qt.IsNil)
+ f.Close()
// Build it again to make sure we read images from file cache.
- b = newBuilder()
+ b = newBuilder("30s")
b.Build(BuildCfg{})
- b.AssertFileContent(filepath.Join(workDir, "public/index.html"), imgExpect)
+ assertImages()
}
diff --git a/hugolib/page__per_output.go b/hugolib/page__per_output.go
index 59de10be3..bc2a0accc 100644
--- a/hugolib/page__per_output.go
+++ b/hugolib/page__per_output.go
@@ -180,7 +180,7 @@ func newPageContentOutput(p *pageState) func(f output.Format) (*pageContentOutpu
needTimeout := !p.renderable || p.shortcodeState.hasShortcodes()
if needTimeout {
- cp.initMain = parent.BranchdWithTimeout(p.s.siteCfg.timeout, func(ctx context.Context) (interface{}, error) {
+ cp.initMain = parent.BranchWithTimeout(p.s.siteCfg.timeout, func(ctx context.Context) (interface{}, error) {
return nil, initContent()
})
} else {
@@ -249,8 +249,10 @@ type pageContentOutput struct {
}
func (p *pageContentOutput) Content() (interface{}, error) {
- p.p.s.initInit(p.initMain, p.p)
- return p.content, nil
+ if p.p.s.initInit(p.initMain, p.p) {
+ return p.content, nil
+ }
+ return nil, nil
}
func (p *pageContentOutput) FuzzyWordCount() int {
diff --git a/hugolib/site.go b/hugolib/site.go
index 0b45c4803..4b4df6451 100644
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -181,11 +181,12 @@ func (init *siteInit) Reset() {
init.menus.Reset()
}
-func (s *Site) initInit(init *lazy.Init, pctx pageContext) {
+func (s *Site) initInit(init *lazy.Init, pctx pageContext) bool {
_, err := init.Do()
if err != nil {
s.h.FatalError(pctx.wrapError(err))
}
+ return err == nil
}
func (s *Site) prepareInits() {
@@ -410,10 +411,23 @@ func newSite(cfg deps.DepsCfg) (*Site, error) {
return nil, err
}
+ timeout := 30 * time.Second
+ if cfg.Language.IsSet("timeout") {
+ switch v := cfg.Language.Get("timeout").(type) {
+ case int:
+ timeout = time.Duration(v) * time.Millisecond
+ case string:
+ d, err := time.ParseDuration(v)
+ if err == nil {
+ timeout = d
+ }
+ }
+ }
+
siteConfig := siteConfigHolder{
sitemap: config.DecodeSitemap(config.Sitemap{Priority: -1, Filename: "sitemap.xml"}, cfg.Language.GetStringMap("sitemap")),
taxonomiesConfig: taxonomies,
- timeout: time.Duration(cfg.Language.GetInt("timeout")) * time.Millisecond,
+ timeout: timeout,
hasCJKLanguage: cfg.Language.GetBool("hasCJKLanguage"),
enableEmoji: cfg.Language.Cfg.GetBool("enableEmoji"),
}