Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(183)

Issue 86290043: code review 86290043: net/http: don't reuse Transport connection unless Reque... (Closed)

Can't Edit
Can't Publish+Mail
Start Review
Created:
10 years, 1 month ago by bradfitz
Modified:
10 years, 1 month ago
Reviewers:
adg
CC:
golang-codereviews, adg, dsymonds, rsc
Visibility:
Public.

Description

net/http: don't reuse Transport connection unless Request.Write finished In a typical HTTP request, the client writes the request, and then the server replies. Go's HTTP client code (Transport) has two goroutines per connection: one writing, and one reading. A third goroutine (the one initiating the HTTP request) coordinates with those two. Because most HTTP requests are done when the server replies, the Go code has always handled connection reuse purely in the readLoop goroutine. But if a client is writing a large request and the server replies before it's consumed the entire request (e.g. it replied with a 403 Forbidden and had no use for the body), it was possible for Go to re-select that connection for a subsequent request before we were done writing the first. That wasn't actually a data race; the second HTTP request would just get enqueued to write its request on the writeLoop. But because the previous writeLoop didn't finish writing (and might not ever), that connection is in a weird state. We really just don't want to get into a state where we're re-using a connection when the server spoke out of turn. This CL changes the readLoop goroutine to verify that the writeLoop finished before returning the connection. In the process, it also fixes a potential goroutine leak where a connection could close but the recycling logic could be blocked forever waiting for the client to read to EOF or error. Now it also selects on the persistConn's close channel, and the closer of that is no longer the readLoop (which was dead locking in some cases before). It's now closed at the same place the underlying net.Conn is closed. This likely fixes or helps Issue 7620. Also addressed some small cosmetic things in the process. Update Issue 7620 Fixes Issue 7569

Patch Set 1 #

Patch Set 2 : diff -r 1eaf29392348 https://go.googlecode.com/hg/ #

Patch Set 3 : diff -r 1eaf29392348 https://go.googlecode.com/hg/ #

Total comments: 14

Patch Set 4 : diff -r 1eaf29392348 https://go.googlecode.com/hg/ #

Patch Set 5 : diff -r 9ef11603cde8 https://go.googlecode.com/hg/ #

Unified diffs Side-by-side diffs Delta from patch set Stats (+181 lines, -40 lines) Patch
M src/pkg/net/http/transport.go View 1 2 3 9 chunks +58 lines, -30 lines 0 comments Download
M src/pkg/net/http/transport_test.go View 1 2 3 4 3 chunks +123 lines, -10 lines 0 comments Download

Messages

Total messages: 6
bradfitz
Hello golang-codereviews@googlegroups.com (cc: adg@golang.org, dsymonds@golang.org, rsc@golang.org), I'd like you to review this change to https://go.googlecode.com/hg/
10 years, 1 month ago (2014-04-10 00:36:21 UTC) #1
adg
https://codereview.appspot.com/86290043/diff/30001/src/pkg/net/http/transport.go File src/pkg/net/http/transport.go (right): https://codereview.appspot.com/86290043/diff/30001/src/pkg/net/http/transport.go#newcode733 src/pkg/net/http/transport.go:733: // whether or not a connection can be reused. ...
10 years, 1 month ago (2014-04-10 03:28:19 UTC) #2
bradfitz
PTAL https://codereview.appspot.com/86290043/diff/30001/src/pkg/net/http/transport.go File src/pkg/net/http/transport.go (right): https://codereview.appspot.com/86290043/diff/30001/src/pkg/net/http/transport.go#newcode733 src/pkg/net/http/transport.go:733: // whether or not a connection can be ...
10 years, 1 month ago (2014-04-10 04:41:32 UTC) #3
bradfitz
Hello golang-codereviews@googlegroups.com, adg@golang.org (cc: dsymonds@golang.org, golang-codereviews@googlegroups.com, rsc@golang.org), Please take another look.
10 years, 1 month ago (2014-04-10 04:41:41 UTC) #4
adg
LGTM
10 years, 1 month ago (2014-04-10 04:46:24 UTC) #5
bradfitz
10 years, 1 month ago (2014-04-10 04:50:27 UTC) #6
*** Submitted as https://code.google.com/p/go/source/detail?r=07e31caba5b6 ***

net/http: don't reuse Transport connection unless Request.Write finished

In a typical HTTP request, the client writes the request, and
then the server replies. Go's HTTP client code (Transport) has
two goroutines per connection: one writing, and one reading. A
third goroutine (the one initiating the HTTP request)
coordinates with those two.

Because most HTTP requests are done when the server replies,
the Go code has always handled connection reuse purely in the
readLoop goroutine.

But if a client is writing a large request and the server
replies before it's consumed the entire request (e.g. it
replied with a 403 Forbidden and had no use for the body), it
was possible for Go to re-select that connection for a
subsequent request before we were done writing the first. That
wasn't actually a data race; the second HTTP request would
just get enqueued to write its request on the writeLoop. But
because the previous writeLoop didn't finish writing (and
might not ever), that connection is in a weird state. We
really just don't want to get into a state where we're
re-using a connection when the server spoke out of turn.

This CL changes the readLoop goroutine to verify that the
writeLoop finished before returning the connection.

In the process, it also fixes a potential goroutine leak where
a connection could close but the recycling logic could be
blocked forever waiting for the client to read to EOF or
error. Now it also selects on the persistConn's close channel,
and the closer of that is no longer the readLoop (which was
dead locking in some cases before). It's now closed at the
same place the underlying net.Conn is closed. This likely fixes
or helps Issue 7620.

Also addressed some small cosmetic things in the process.

Update Issue 7620
Fixes Issue 7569

LGTM=adg
R=golang-codereviews, adg
CC=dsymonds, golang-codereviews, rsc
https://codereview.appspot.com/86290043
Sign in to reply to this message.

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b