HTTP Server Broken Pipe Errors - pikachule/golang_notes GitHub Wiki

MoneyWorthington 於 1 年前 發表

I've been spending some time tracking down issues in a production site that I believe are related to these errors showing up in the logs:

write tcp 204.248.121.130:41259: broken pipe

It looked like the errors were coming from potentially random places in the HTML template, so on a whim, I decided to try a solution that actually worked, to my surprise. The fix I came up with was to buffer the output by changing this:

// where `w` is an instance of http.ResponseWriter
if err := views.ExecuteTemplate(w, "template", context); err != nil {
    // handle error
}

to this:

var buf bytes.Buffer
if err := views.ExecuteTemplate(&buf, "template", context); err != nil {
    // handle error
} else {
    io.Copy(w, &buf)
}

My question is: why? Why does buffering the data written to http.ResponseWriter fix this issue? The only thing I can think of is that there's some kind of timeout from the first call to w.Write() until the response is sent and the pipe is closed, since the template writes as it goes, but with the buffer that gap is drastically narrowed.

It should be noted that it took using a load generator to be able to reproduce the errors outside of production (note to self for all future projects: use a load generator before deploying to production), and the templates themselves are pretty sizeable and have a lot of room for optimization.

What gives?

⚠️ **GitHub.com Fallback** ⚠️