Skip to content

text/template: docs say "A template may be executed safely in parallel." which is misleading #19439

@Dieterbe

Description

@Dieterbe

Hello,
first of, Go is awesome. I love it. thank you very much. But I recently ran into a snag that I think other people could run into as well, and I think extending the docs a bit would help. That's why I created https://go-review.googlesource.com/c/37444/ but I was asked to create an issue to justify the proposed change. so here we go.

What version of Go are you using (go version)?

1.8

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/dieter/go"
GORACE=""
GOROOT="/usr/lib/go"
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/dieter/go-build064122595=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"

What did you do?

I was recently working on a tool which consumes data from kafka and prints it to stdout via text/template, specifically Template.Execute() which was passed in os.Stdout as io.Writer.
The output was garbled (snippets of different execute calls intermingled). I tried various solutions, such as passing it a custom type implementing io.Writer, which protected os.Stdout with a lock; to no avail. output was still garbled.
We discussed it in the performance slack channel
(see https://gophers.slack.com/archives/performance/p1486655425001817)
, where a bunch of people tried to help (e.g. by looking into the atomicity of Write syscalls, http://man7.org/linux/man-pages/man2/write.2.html#BUGS, the go source code of how it calls syscall.Write, etc )

After a while I figured out template.Execute calls Write() multiple times as it walks the tree and prints individual pieces. Which was a bit confusing since
https://golang.org/pkg/text/template/#Template.Execute says "A template may be executed safely in parallel." my experience was by executing the template in parallel my output was getting corrupted. The docs didn't say anything about needing to execute into different writers, or needing to lock around the entire Template.Execute call if you want to use stdout.

So this is why I filed https://go-review.googlesource.com/c/37444/

cheers,
Dieter

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions