We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extracted from flaky production tests.
ExecuteTemplate is documented to allow concurrent calls:
ExecuteTemplate
A template may be executed safely in parallel, although if parallel executions share a Writer the output may be interleaved.
https://play.golang.org/p/MHNbSuG9gOj
package main import ( "html/template" "io" "strings" "sync" ) func main() { tmpl, err := template.New("a").Parse(`{{template "t"}}`) if err != nil { panic(err) } tmpl.New("b").Parse(`{{template "h"}}{{template "t"}}`) tmpl.New("h").Parse(`<style>{{template "s"}}</style>`) tmpl.New("t").Parse("") tmpl.New("s").Parse(strings.Repeat("🏎", 10000)) var wg sync.WaitGroup wg.Add(100) for i := 0; i < 100; i++ { name := "a" if i&1 == 0 { name = "b" } go func(name string) { defer wg.Done() tmpl.ExecuteTemplate(io.Discard, name, nil) }(name) } wg.Wait() }
Result:
================== WARNING: DATA RACE Write at 0x00c00011c540 by goroutine 35: runtime.mapaccess2_faststr() /Users/josh/go/1.16/src/runtime/map_faststr.go:107 +0x48c text/template.(*Template).associate() /Users/josh/go/1.16/src/text/template/template.go:227 +0x160 text/template.(*Template).AddParseTree() /Users/josh/go/1.16/src/text/template/template.go:133 +0x218 html/template.(*escaper).commit() /Users/josh/go/1.16/src/html/template/escape.go:812 +0x1fc html/template.escapeTemplate() /Users/josh/go/1.16/src/html/template/escape.go:38 +0x264 html/template.(*Template).lookupAndEscapeTemplate() /Users/josh/go/1.16/src/html/template/template.go:163 +0x2a8 html/template.(*Template).ExecuteTemplate() /Users/josh/go/1.16/src/html/template/template.go:135 +0x38 main.main.func1() /Users/josh/grrr/x.go:28 +0x94 Previous read at 0x00c00011c540 by goroutine 34: runtime.evacuate_fast64() /Users/josh/go/1.16/src/runtime/map_fast64.go:375 +0x3dc text/template.(*state).walkTemplate() /Users/josh/go/1.16/src/text/template/exec.go:404 +0xf0 text/template.(*state).walk() /Users/josh/go/1.16/src/text/template/exec.go:269 +0x214 text/template.(*state).walk() /Users/josh/go/1.16/src/text/template/exec.go:264 +0x140 text/template.(*Template).execute() /Users/josh/go/1.16/src/text/template/exec.go:220 +0x214 text/template.(*Template).Execute() /Users/josh/go/1.16/src/text/template/exec.go:203 +0xb8 html/template.(*Template).ExecuteTemplate() /Users/josh/go/1.16/src/html/template/template.go:139 +0x7c main.main.func1() /Users/josh/grrr/x.go:28 +0x94 Goroutine 35 (running) created at: main.main() /Users/josh/grrr/x.go:26 +0x21c Goroutine 34 (finished) created at: main.main() /Users/josh/grrr/x.go:26 +0x21c ================== ================== WARNING: DATA RACE Write at 0x00c00011f020 by goroutine 35: text/template.(*Template).associate() /Users/josh/go/1.16/src/text/template/template.go:227 +0x174 text/template.(*Template).AddParseTree() /Users/josh/go/1.16/src/text/template/template.go:133 +0x218 html/template.(*escaper).commit() /Users/josh/go/1.16/src/html/template/escape.go:812 +0x1fc html/template.escapeTemplate() /Users/josh/go/1.16/src/html/template/escape.go:38 +0x264 html/template.(*Template).lookupAndEscapeTemplate() /Users/josh/go/1.16/src/html/template/template.go:163 +0x2a8 html/template.(*Template).ExecuteTemplate() /Users/josh/go/1.16/src/html/template/template.go:135 +0x38 main.main.func1() /Users/josh/grrr/x.go:28 +0x94 Previous read at 0x00c00011f020 by goroutine 12: text/template.(*state).walkTemplate() /Users/josh/go/1.16/src/text/template/exec.go:404 +0x100 text/template.(*state).walk() /Users/josh/go/1.16/src/text/template/exec.go:269 +0x214 text/template.(*state).walk() /Users/josh/go/1.16/src/text/template/exec.go:264 +0x140 text/template.(*state).walkTemplate() /Users/josh/go/1.16/src/text/template/exec.go:418 +0x2f4 text/template.(*state).walk() /Users/josh/go/1.16/src/text/template/exec.go:269 +0x214 text/template.(*state).walk() /Users/josh/go/1.16/src/text/template/exec.go:264 +0x140 text/template.(*Template).execute() /Users/josh/go/1.16/src/text/template/exec.go:220 +0x214 text/template.(*Template).Execute() /Users/josh/go/1.16/src/text/template/exec.go:203 +0xb8 html/template.(*Template).ExecuteTemplate() /Users/josh/go/1.16/src/html/template/template.go:139 +0x7c main.main.func1() /Users/josh/grrr/x.go:28 +0x94 Goroutine 35 (running) created at: main.main() /Users/josh/grrr/x.go:26 +0x21c Goroutine 12 (finished) created at: main.main() /Users/josh/grrr/x.go:26 +0x21c ================== Found 2 data race(s) exit status 66
The text was updated successfully, but these errors were encountered:
This is from 1.16. Did you also try 1.17beta1?
Sorry, something went wrong.
Yep. Doesn't reproduce on 1.17beta.
Still might be worth tracking for a cherry pick to 1.16.
496d7c6 is the fix.
@gopherbot, please open backport issues.
Backport issue(s) opened: #47041 (for 1.15), #47042 (for 1.16).
Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://golang.org/wiki/MinorReleases.
No branches or pull requests
Extracted from flaky production tests.
ExecuteTemplate
is documented to allow concurrent calls:https://play.golang.org/p/MHNbSuG9gOj
Result:
The text was updated successfully, but these errors were encountered: