ref: b590de6917ea371d8b03d95a993a6fc38b967b5d
parent: 49045b1cbc67774edc99f69ad8b9bfd7fd826c38
author: Nate Finch <[email protected]>
date: Sun Sep 14 03:23:03 EDT 2014
limit the number of goroutines used in taxonomy rendering to gomaxprocs*4
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -15,6 +15,7 @@
import (
"bytes"
+ "errors"
"fmt"
"html/template"
"io"
@@ -664,7 +665,7 @@
}
// Render pages each corresponding to a markdown file
-func (s *Site) RenderPages() (err error) {
+func (s *Site) RenderPages() error {
results := make(chan error)
pages := make(chan *Page)
@@ -680,7 +681,7 @@
errs := make(chan error)
- go renderCollator(s, results, errs)
+ go errorCollator(results, errs)
for _, page := range s.Pages {
pages <- page
@@ -692,7 +693,11 @@
close(results)
- return <-errs
+ err := <-errs
+ if err != nil {
+ return fmt.Errorf("Error(s) rendering pages: %s", err)
+ }
+ return nil
}
func pageRenderer(s *Site, pages <-chan *Page, results chan<- error, wg *sync.WaitGroup) {
@@ -717,19 +722,19 @@
}
}
-func renderCollator(s *Site, results <-chan error, errs chan<- error) {
+func errorCollator(results <-chan error, errs chan<- error) {
errMsgs := []string{}
for err := range results {
if err != nil {
errMsgs = append(errMsgs, err.Error())
- continue
}
}
if len(errMsgs) == 0 {
errs <- nil
- return
+ } else {
+ errs <- errors.New(strings.Join(errMsgs, "\n"))
}
- errs <- fmt.Errorf("Errors rendering pages: %s", strings.Join(errMsgs, "\n"))
+ close(errs)
}
func (s *Site) appendThemeTemplates(in []string) []string {
@@ -760,45 +765,80 @@
}
}
+type taxRenderInfo struct {
+ key string
+ pages WeightedPages
+ singular string
+ plural string
+}
+
// Render the listing pages based on the meta data
// each unique term within a taxonomy will have a page created
-func (s *Site) RenderTaxonomiesLists() (err error) {
- var wg sync.WaitGroup
+func (s *Site) RenderTaxonomiesLists() error {
+ wg := &sync.WaitGroup{}
- taxonomies := viper.GetStringMapString("Taxonomies")
- for sing, pl := range taxonomies {
- for key, oo := range s.Taxonomies[pl] {
- wg.Add(1)
- go func(k string, o WeightedPages, singular string, plural string) (err error) {
- defer wg.Done()
- base := plural + "/" + k
- n := s.NewNode()
- n.Title = strings.Title(k)
- s.setUrls(n, base)
- n.Date = o[0].Page.Date
- n.Data[singular] = o
- n.Data["Pages"] = o.Pages()
- layouts := []string{"taxonomy/" + singular + ".html", "indexes/" + singular + ".html", "_default/taxonomy.html", "_default/list.html"}
- err = s.render(n, base+".html", s.appendThemeTemplates(layouts)...)
- if err != nil {
- return err
- }
+ taxes := make(chan taxRenderInfo)
+ results := make(chan error)
- if !viper.GetBool("DisableRSS") {
- // XML Feed
- s.setUrls(n, base+".xml")
- rssLayouts := []string{"taxonomy/" + singular + ".rss.xml", "_default/rss.xml", "rss.xml", "_internal/_default/rss.xml"}
- err := s.render(n, base+".xml", s.appendThemeTemplates(rssLayouts)...)
- if err != nil {
- return err
- }
- }
- return
- }(key, oo, sing, pl)
+ procs := getGoMaxProcs()
+
+ for i := 0; i < procs*4; i++ {
+ wg.Add(1)
+ go taxonomyRenderer(s, taxes, results, wg)
+ }
+
+ errs := make(chan error)
+
+ go errorCollator(results, errs)
+
+ taxonomies := viper.GetStringMapString("Taxonomies")
+ for singular, plural := range taxonomies {
+ for key, pages := range s.Taxonomies[plural] {
+ taxes <- taxRenderInfo{key, pages, singular, plural}
}
}
+ close(taxes)
+
wg.Wait()
+
+ close(results)
+
+ err := <-errs
+ if err != nil {
+ return fmt.Errorf("Error(s) rendering taxonomies: %s", err)
+ }
return nil
+}
+
+func taxonomyRenderer(s *Site, taxes <-chan taxRenderInfo, results chan<- error, wg *sync.WaitGroup) {
+ defer wg.Done()
+ for t := range taxes {
+ base := t.plural + "/" + t.key
+ n := s.NewNode()
+ n.Title = strings.Title(t.key)
+ s.setUrls(n, base)
+ n.Date = t.pages[0].Page.Date
+ n.Data[t.singular] = t.pages
+ n.Data["Pages"] = t.pages.Pages()
+ layouts := []string{"taxonomy/" + t.singular + ".html", "indexes/" + t.singular + ".html", "_default/taxonomy.html", "_default/list.html"}
+ err := s.render(n, base+".html", s.appendThemeTemplates(layouts)...)
+ if err != nil {
+ results <- err
+ continue
+ }
+
+ if !viper.GetBool("DisableRSS") {
+ // XML Feed
+ s.setUrls(n, base+".xml")
+ rssLayouts := []string{"taxonomy/" + t.singular + ".rss.xml", "_default/rss.xml", "rss.xml", "_internal/_default/rss.xml"}
+ err := s.render(n, base+".xml", s.appendThemeTemplates(rssLayouts)...)
+ if err != nil {
+ results <- err
+ continue
+ }
+ }
+ results <- nil
+ }
}
// Render a page per taxonomy that lists the terms for that taxonomy