shithub: hugo

Download patch

ref: 03122e51fa41d0a289054eedc2d6fffd7f9f2e0b
parent: e5200ddaa4d44934cec2ffbbb02a51ff69488c14
author: Bjørn Erik Pedersen <[email protected]>
date: Tue Mar 7 04:55:17 EST 2017

hugolib: Revert to using Page as the render chan type

Changing it to PageOutput was a mistake. You may think that the increased parallelism should be a good thing.

But not so much with the increased lock contention and more complex concurrency model.

--- a/hugolib/page_output.go
+++ b/hugolib/page_output.go
@@ -25,9 +25,11 @@
 	outputType output.Type
 }
 
-func newPageOutput(p *Page, outputType output.Type) *PageOutput {
+func newPageOutput(p *Page, createCopy bool, outputType output.Type) *PageOutput {
 	// TODO(bep) output avoid copy of first?
-	p = p.copy()
+	if createCopy {
+		p = p.copy()
+	}
 	return &PageOutput{Page: p, outputType: outputType}
 }
 
--- a/hugolib/site_render.go
+++ b/hugolib/site_render.go
@@ -20,8 +20,9 @@
 	"sync"
 	"time"
 
-	bp "github.com/spf13/hugo/bufferpool"
 	"github.com/spf13/hugo/output"
+
+	bp "github.com/spf13/hugo/bufferpool"
 )
 
 // renderPages renders pages each corresponding to a markdown file.
@@ -29,7 +30,7 @@
 func (s *Site) renderPages() error {
 
 	results := make(chan error)
-	pages := make(chan *PageOutput)
+	pages := make(chan *Page)
 	errs := make(chan error)
 
 	go errorCollator(results, errs)
@@ -44,9 +45,7 @@
 	}
 
 	for _, page := range s.Pages {
-		for _, outputType := range page.outputTypes {
-			pages <- newPageOutput(page, outputType)
-		}
+		pages <- page
 	}
 
 	close(pages)
@@ -62,43 +61,45 @@
 	return nil
 }
 
-func pageRenderer(s *Site, pages <-chan *PageOutput, results chan<- error, wg *sync.WaitGroup) {
+func pageRenderer(s *Site, pages <-chan *Page, results chan<- error, wg *sync.WaitGroup) {
 	defer wg.Done()
-	for p := range pages {
-		// TODO(bep) output check if some of the interface{} methods below checks for *Page
-		var layouts []string
+	for page := range pages {
+		for i, outputType := range page.outputTypes {
+			pageOutput := newPageOutput(page, i > 0, outputType)
 
-		if len(p.layoutsCalculated) > 0 {
-			// TODO(bep) output
-			layouts = p.layoutsCalculated
-		} else {
-			layouts = s.layoutHandler.For(p.layoutIdentifier, "", p.outputType)
-		}
+			var layouts []string
 
-		switch p.outputType {
+			if len(pageOutput.layoutsCalculated) > 0 {
+				// TODO(bep) output
+				layouts = pageOutput.layoutsCalculated
+			} else {
+				layouts = s.layoutHandler.For(pageOutput.layoutIdentifier, "", pageOutput.outputType)
+			}
 
-		case output.HTMLType:
-			targetPath := p.TargetPath()
+			switch pageOutput.outputType {
 
-			s.Log.DEBUG.Printf("Render %s to %q with layouts %q", p.Kind, targetPath, layouts)
+			case output.HTMLType:
+				targetPath := pageOutput.TargetPath()
 
-			if err := s.renderAndWritePage("page "+p.FullFilePath(), targetPath, p, layouts...); err != nil {
-				results <- err
-			}
+				s.Log.DEBUG.Printf("Render %s to %q with layouts %q", pageOutput.Kind, targetPath, layouts)
 
-			// Taxonomy terms have no page set to paginate, so skip that for now.
-			if p.IsNode() {
-				if err := s.renderPaginator(p); err != nil {
+				if err := s.renderAndWritePage("page "+pageOutput.FullFilePath(), targetPath, pageOutput, layouts...); err != nil {
 					results <- err
 				}
-			}
 
-		case output.RSSType:
-			if err := s.renderRSS(p); err != nil {
-				results <- err
+				// Taxonomy terms have no page set to paginate, so skip that for now.
+				if pageOutput.IsNode() {
+					if err := s.renderPaginator(pageOutput); err != nil {
+						results <- err
+					}
+				}
+
+			case output.RSSType:
+				if err := s.renderRSS(pageOutput); err != nil {
+					results <- err
+				}
 			}
 		}
-
 	}
 }