Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read response body for TCP connection reuse #1576

Merged
merged 2 commits into from
Aug 11, 2020
Merged

Conversation

itsksaurabh
Copy link
Contributor

@itsksaurabh itsksaurabh commented Jul 16, 2020

According to the official Go docs:
https://golang.org/pkg/net/http/#Body

// The http Client and Transport guarantee that Body is always
// non-nil, even on responses without a body or responses with
// a zero-length body. It is the caller's responsibility to
// close Body. The default HTTP client's Transport may not
// reuse HTTP/1.x "keep-alive" TCP connections if the Body is
// not read to completion and closed.

To ensure http.Client connection reuse, I did the following things:

  • Read until Response is complete (i.e. ioutil.ReadAll(resp.Body) or similar)
  • Call Body.Close()

Closes #1575

@googlebot
Copy link

We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and then comment @googlebot I fixed it.. If the bot doesn't comment, it means it doesn't think anything has changed.

ℹ️ Googlers: Go here for more info.

@codecov
Copy link

codecov bot commented Jul 16, 2020

Codecov Report

Merging #1576 into master will increase coverage by 0.03%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1576      +/-   ##
==========================================
+ Coverage   67.95%   67.98%   +0.03%     
==========================================
  Files          96       96              
  Lines        8762     8772      +10     
==========================================
+ Hits         5954     5964      +10     
  Misses       1898     1898              
  Partials      910      910              
Impacted Files Coverage Δ
github/github.go 89.91% <100.00%> (+0.23%) ⬆️
github/reactions.go 64.50% <0.00%> (ø)
github/actions_runners.go 51.35% <0.00%> (ø)
github/issues_comments.go 78.87% <0.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e881974...bd73ea4. Read the comment docs.

@itsksaurabh
Copy link
Contributor Author

@googlebot I fixed it.

@googlebot
Copy link

CLAs look good, thanks!

ℹ️ Googlers: Go here for more info.

@googlebot googlebot added cla: yes Indication that the PR author has signed a Google Contributor License Agreement. and removed cla: no labels Jul 16, 2020
@itsksaurabh itsksaurabh changed the title HTTP Client Improvent: Reuse Underlying TCP connection HTTP Client Improvement: Reuse Underlying TCP connection Jul 16, 2020
Copy link
Collaborator

@gmlewis gmlewis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, @itsksaurabh !
LGTM.

Awaiting second LGTM before merging.

@gmlewis gmlewis requested a review from wesleimp July 23, 2020 00:21
@itsksaurabh
Copy link
Contributor Author

@gmlewis It's my pleasure! :)
Thank you for your approval. 🙏

Copy link
Collaborator

@gmlewis gmlewis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why this says I haven't reviewed it, which I obviously have in the Conversation thread.

Still awaiting a second LGTM before merging.

github/github.go Outdated
io.CopyN(ioutil.Discard, resp.Body, maxBodySlurpSize)
}

if rerr := resp.Body.Close(); err == nil {
Copy link

@philippfranke philippfranke Aug 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, this if condition can be removed because err is not part of the named return values. Therefore, the error is never returned if any occur.

Nonetheless, it's a really interesting issue you fixed 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@philippfranke Thank you for the review. I am glad that you liked the PR.
Yes, I also agree with your point. There is no need to check for error as it is not part of the named return values. Also, If it fails, the Transport won't reuse it anyway.

Copy link
Contributor Author

@itsksaurabh itsksaurabh Aug 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@philippfranke I just changed the code. Please let me know if it seems good to you or if some improvements are needed. Thanks! :)

Copy link

@philippfranke philippfranke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@itsksaurabh itsksaurabh changed the title HTTP Client Improvement: Reuse Underlying TCP connection HTTP Client Improvement Aug 11, 2020
@itsksaurabh
Copy link
Contributor Author

Thank you for the approval @philippfranke ♥️

@gmlewis
Copy link
Collaborator

gmlewis commented Aug 11, 2020

Thank you, @philippfranke !
Merging.

@gmlewis gmlewis changed the title HTTP Client Improvement Read response body for TCP connection reuse Aug 11, 2020
@gmlewis gmlewis merged commit e19d4dd into google:master Aug 11, 2020
Copy link

@bvaliev bvaliev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if resp.ContentLength == -1
not needed here because it's int64 and it is always less than -1 if less than 2048

Checking resp for nil is unnecessary if the code is written according to Go standards because if err != nil is returned then resp must be nil

Generally you had to write resp.ContentLength <= 2048 instead 565 and 566 strings

@gmlewis
Copy link
Collaborator

gmlewis commented Nov 11, 2020

Yes, @bvaliev - this PR has issues. PRs are welcome and we'll review proposed changes.

@itsksaurabh
Copy link
Contributor Author

if resp.ContentLength == -1
not needed here because it's int64 and it is always less than -1 if less than 2048

Checking resp for nil is unnecessary if the code is written according to Go standards because if err != nil is returned then resp must be nil

Generally you had to write resp.ContentLength <= 2048 instead 565 and 566 strings

@bvaliev I am not sure about everything you mentioned above. :)

    // ContentLength records the length of the associated content.
    // The value -1 indicates that the length is unknown.
    // Values >= 0 indicate that the given number of bytes may
    // be read from Body.
    //
    // For client requests, a value of 0 with a non-nil Body is
    // also treated as unknown.
    ContentLength int64

https://golang.org/pkg/net/http/

Do you have them somewhere specified in the docs? If so I would love to learn from it. Thanks!

@itsksaurabh
Copy link
Contributor Author

itsksaurabh commented Nov 12, 2020

@gmlewis Thank you for your time on this PR. I would like to share with you that the latest official Go Http package does connection reuse internally now in the same way I did in the PR as you could see here. This shows the changes were needed indeed. So now, it is possible to clean up the code.

I have created a PR #1645 for it and now we could happily remove the code. Please have a look :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug cla: yes Indication that the PR author has signed a Google Contributor License Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

determine if there are situations when io.CopyN is needed to reuse underlying TCP connection
5 participants