Fix data race in non-renderable pages

Fixes #1601
This commit is contained in:
Bjørn Erik Pedersen 2015-12-18 09:54:46 +01:00
parent 0c01fef321
commit 8cea428802
3 changed files with 28 additions and 18 deletions

View file

@ -66,6 +66,7 @@ type Page struct {
contentType string contentType string
renderable bool renderable bool
Layout string Layout string
layoutsCalculated []string
linkTitle string linkTitle string
frontmatter []byte frontmatter []byte
rawContent []byte rawContent []byte
@ -288,6 +289,10 @@ func (p *Page) Section() string {
} }
func (p *Page) layouts(l ...string) []string { func (p *Page) layouts(l ...string) []string {
if len(p.layoutsCalculated) > 0 {
return p.layoutsCalculated
}
if p.Layout != "" { if p.Layout != "" {
return layouts(p.Type(), p.Layout) return layouts(p.Type(), p.Layout)
} }

View file

@ -920,6 +920,26 @@ func (s *Site) RenderPages() error {
procs := getGoMaxProcs() procs := getGoMaxProcs()
// this cannot be fanned out to multiple Go routines
// See issue #1601
// TODO(bep): Check the IsRenderable logic.
for _, p := range s.Pages {
var layouts []string
if !p.IsRenderable() {
self := "__" + p.TargetPath()
_, err := s.Tmpl.New(self).Parse(string(p.Content))
if err != nil {
results <- err
continue
}
layouts = append(layouts, self)
} else {
layouts = append(layouts, p.layouts()...)
layouts = append(layouts, "_default/single.html")
}
p.layoutsCalculated = layouts
}
wg := &sync.WaitGroup{} wg := &sync.WaitGroup{}
for i := 0; i < procs*4; i++ { for i := 0; i < procs*4; i++ {
@ -951,22 +971,7 @@ func (s *Site) RenderPages() error {
func pageRenderer(s *Site, pages <-chan *Page, results chan<- error, wg *sync.WaitGroup) { func pageRenderer(s *Site, pages <-chan *Page, results chan<- error, wg *sync.WaitGroup) {
defer wg.Done() defer wg.Done()
for p := range pages { for p := range pages {
var layouts []string err := s.renderAndWritePage("page "+p.FullFilePath(), p.TargetPath(), p, s.appendThemeTemplates(p.layouts())...)
if !p.IsRenderable() {
self := "__" + p.TargetPath()
_, err := s.Tmpl.New(self).Parse(string(p.Content))
if err != nil {
results <- err
continue
}
layouts = append(layouts, self)
} else {
layouts = append(layouts, p.layouts()...)
layouts = append(layouts, "_default/single.html")
}
err := s.renderAndWritePage("page "+p.FullFilePath(), p.TargetPath(), p, s.appendThemeTemplates(layouts)...)
if err != nil { if err != nil {
results <- err results <- err
} }

View file

@ -158,7 +158,7 @@ func TestRenderThing(t *testing.T) {
templateName := fmt.Sprintf("foobar%d", i) templateName := fmt.Sprintf("foobar%d", i)
err = s.addTemplate(templateName, test.template) err = s.addTemplate(templateName, test.template)
if err != nil { if err != nil {
t.Fatalf("Unable to add template") t.Fatalf("Unable to add template: %s", err)
} }
p.Content = template.HTML(p.Content) p.Content = template.HTML(p.Content)
@ -203,7 +203,7 @@ func TestRenderThingOrDefault(t *testing.T) {
templateName := fmt.Sprintf("default%d", i) templateName := fmt.Sprintf("default%d", i)
err = s.addTemplate(templateName, test.template) err = s.addTemplate(templateName, test.template)
if err != nil { if err != nil {
t.Fatalf("Unable to add template") t.Fatalf("Unable to add template: %s", err)
} }
var err2 error var err2 error