I had thought to set a buffer size of 2048, half the websocket package
default of 4096. But it turns out when you don't set a buffer size, the
websocket package reuses the HTTP server's read/write buffers, which
empirically already have a size of 2048.
$ go test -bench=BenchmarkUpgradeBufferSize -benchmem -benchtime=5s
BenchmarkUpgradeBufferSize/0-4 25669 234566 ns/op 32604 B/op 113 allocs/op
BenchmarkUpgradeBufferSize/128-4 24739 238283 ns/op 24325 B/op 117 allocs/op
BenchmarkUpgradeBufferSize/1024-4 25352 238885 ns/op 28087 B/op 116 allocs/op
BenchmarkUpgradeBufferSize/2048-4 22660 234890 ns/op 32444 B/op 116 allocs/op
BenchmarkUpgradeBufferSize/4096-4 25668 232591 ns/op 41672 B/op 116 allocs/op
BenchmarkUpgradeBufferSize/8192-4 24908 240755 ns/op 59103 B/op 116 allocs/op
Unless something externally called Write after Close, the
writeLoop(ws, pr2) goroutine would run forever, because nothing would
ever close pw2/pr2.
https://bugs.torproject.org/33367#comment:4