hugolib: Revert to using Page as the render chan type
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Tue, 7 Mar 2017 08:55:17 +0000 (09:55 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 27 Mar 2017 13:43:56 +0000 (15:43 +0200)
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.

hugolib/page_output.go
hugolib/site_render.go

index 79b7ead9a696a37c096a1800ac701cecd4adaa44..50605bddf723dc268ad8239c795701a41210c5ac 100644 (file)
@@ -25,9 +25,11 @@ type PageOutput struct {
        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}
 }
 
index 53873f6fcb2d51a1dc0dca24a42957dcfe8aca3f..54cba59bcf93309bd7fca3afcd09cf010d839386 100644 (file)
@@ -20,8 +20,9 @@ import (
        "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 @@ import (
 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 @@ func (s *Site) renderPages() error {
        }
 
        for _, page := range s.Pages {
-               for _, outputType := range page.outputTypes {
-                       pages <- newPageOutput(page, outputType)
-               }
+               pages <- page
        }
 
        close(pages)
@@ -62,43 +61,45 @@ func (s *Site) renderPages() error {
        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
+                               }
                        }
                }
-
        }
 }