]> Cypherpunks repositories - gostls13.git/commitdiff
template: warn about interleaved nature of writes
authorDieter Plaetinck <dieter@raintank.io>
Fri, 10 Feb 2017 10:54:58 +0000 (11:54 +0100)
committerRob Pike <r@golang.org>
Fri, 5 May 2017 17:58:56 +0000 (17:58 +0000)
Execute incurs separate writes for each "step", e.g. each
variable that needs to be printed, and the final newline.
While it is correct to state that templates can be executed
concurrently, there is a more subtle nuance that is easily missed:
when writing to the same writer, the writes from concurrent execute
calls can be interleaved, leading to unexpected output.

Change-Id: I0abbd7960d8a8d15e109a8a3eeff3b43b852bbbf
Reviewed-on: https://go-review.googlesource.com/37444
Reviewed-by: Rob Pike <r@golang.org>
src/html/template/template.go
src/text/template/doc.go
src/text/template/exec.go

index e1f179abc221ad9445903f187bc1a3629407ebee..246ef04dbefda0f0c16728724b505c24191767f3 100644 (file)
@@ -112,7 +112,8 @@ func (t *Template) escape() error {
 // If an error occurs executing the template or writing its output,
 // execution stops, but partial results may already have been written to
 // the output writer.
-// A template may be executed safely in parallel.
+// A template may be executed safely in parallel, although if parallel
+// executions share a Writer the output may be interleaved.
 func (t *Template) Execute(wr io.Writer, data interface{}) error {
        if err := t.escape(); err != nil {
                return err
@@ -125,7 +126,8 @@ func (t *Template) Execute(wr io.Writer, data interface{}) error {
 // If an error occurs executing the template or writing its output,
 // execution stops, but partial results may already have been written to
 // the output writer.
-// A template may be executed safely in parallel.
+// A template may be executed safely in parallel, although if parallel
+// executions share a Writer the output may be interleaved.
 func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error {
        tmpl, err := t.lookupAndEscapeTemplate(name)
        if err != nil {
index fe59e3f74e87d7667e2d1f571a5a237d4539284a..b35fe39ecc9876e97776710c9863e4cbc90cf5e8 100644 (file)
@@ -20,7 +20,8 @@ The input text for a template is UTF-8-encoded text in any format.
 "{{" and "}}"; all text outside actions is copied to the output unchanged.
 Except for raw strings, actions may not span newlines, although comments can.
 
-Once parsed, a template may be executed safely in parallel.
+Once parsed, a template may be executed safely in parallel, although if parallel
+executions share a Writer the output may be interleaved.
 
 Here is a trivial example that prints "17 items are made of wool".
 
index 0e517a6ec3bd3fc90cdeabe0e65f4e24607763bc..e54a579afd19253dba394895f77d6c798d0fa239 100644 (file)
@@ -153,7 +153,8 @@ func errRecover(errp *error) {
 // If an error occurs executing the template or writing its output,
 // execution stops, but partial results may already have been written to
 // the output writer.
-// A template may be executed safely in parallel.
+// A template may be executed safely in parallel, although if parallel
+// executions share a Writer the output may be interleaved.
 func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error {
        var tmpl *Template
        if t.common != nil {
@@ -170,7 +171,8 @@ func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{})
 // If an error occurs executing the template or writing its output,
 // execution stops, but partial results may already have been written to
 // the output writer.
-// A template may be executed safely in parallel.
+// A template may be executed safely in parallel, although if parallel
+// executions share a Writer the output may be interleaved.
 //
 // If data is a reflect.Value, the template applies to the concrete
 // value that the reflect.Value holds, as in fmt.Print.