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

add gzip compression to GET and LIST requests #45666

Merged
merged 1 commit into from
Jun 6, 2017

Conversation

ilackarms
Copy link
Contributor

@ilackarms ilackarms commented May 11, 2017

Fixes #44164

Enable compressed response bodies for non-watch GET and LIST requests on API Objects.

What this PR does / why we need it: Adds compression via Accept-Encoding header, returns Content-Encoding header on responses (only supports gzip at this time). Enabled solely for GET and LIST requests which can return very large response bodies.

Special notes for your reviewer:

See #44164 for discussion.

Release note:

@k8s-ci-robot
Copy link
Contributor

Thanks for your pull request. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please follow instructions at https://github.com/kubernetes/kubernetes/wiki/CLA-FAQ to sign the CLA.

It may take a couple minutes for the CLA signature to be fully registered; after that, please reply here with a new comment and we'll verify. Thanks.


Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

@k8s-ci-robot k8s-ci-robot added cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels May 11, 2017
@k8s-ci-robot
Copy link
Contributor

Hi @ilackarms. Thanks for your PR.

I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with @k8s-bot ok to test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

@k8s-github-robot k8s-github-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. release-note Denotes a PR that will be considered when it comes time to generate release notes. labels May 11, 2017
@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. and removed cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. labels May 11, 2017
@gmarek gmarek assigned deads2k and unassigned gmarek May 11, 2017
@gmarek
Copy link
Contributor

gmarek commented May 11, 2017

cc @kubernetes/sig-api-machinery-pr-reviews

@k8s-ci-robot k8s-ci-robot added the sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. label May 11, 2017
@deads2k
Copy link
Contributor

deads2k commented May 11, 2017

@k8s-bot ok to test

@k8s-ci-robot k8s-ci-robot removed the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label May 11, 2017
}

const (
header_AcceptEncoding = "Accept-Encoding"
Copy link
Contributor

Choose a reason for hiding this comment

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

kube convention doesn't use underscores in constant names.

func WithCompression(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
//don't compress watches
if req.URL.Query().Get("watch") == "true" {
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor

@deads2k deads2k May 11, 2017

Choose a reason for hiding this comment

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

With that info, you can whitelist instead of blacklist. Or you can blacklist more effectively.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thanks for the review, I'll look into this now

case encoding_deflate:
compressor = zlib.NewWriter(w)
default:
panic(encoding + " not a valid compression type")
Copy link
Contributor

Choose a reason for hiding this comment

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

We prefer returning and error and letting the caller handle it. In this case, why wouldn't we degrade to a non-compressed response instead of dying?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This shouldn't be here at all; wantsCompression simply returns false if the user specifies a compression type that doesn't exactly match gzip or deflate. I'll fix this in my next commit

}

func RestfulWithCompression(function restful.RouteFunction) restful.RouteFunction {
return restful.RouteFunction(func(request *restful.Request, response *restful.Response) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I expected this to delegate to WithCompression

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does the following seem right to you? I feel like I'm messing with restful internals here, but this was how I implemented the delegation:

func RestfulWithCompression(function restful.RouteFunction) restful.RouteFunction {
	return restful.RouteFunction(func(request *restful.Request, response *restful.Response) {
		handler := WithCompression(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
			response.ResponseWriter = w
			request.Request = req
			function(request, response)
		}))
		handler.ServeHTTP(response.ResponseWriter, request.Request)
	})
}

I didn't want to go with this as I was more comfortable being explicit with the code (despite their being code duplication)

Copy link
Contributor

Choose a reason for hiding this comment

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

Does the following seem right to you? I

Looks like it would work. Not pretty, but workable

@ilackarms ilackarms force-pushed the compression branch 2 times, most recently from bdf7eda to 0acde54 Compare May 13, 2017 14:17
@deads2k
Copy link
Contributor

deads2k commented May 17, 2017

@k8s-bot gce etcd3 e2e test this

@deads2k
Copy link
Contributor

deads2k commented May 17, 2017

squash, fix gofmt (verify) and I'll take another pass

@ilackarms ilackarms force-pushed the compression branch 3 times, most recently from e296af3 to 20b37cb Compare May 17, 2017 23:44
@deads2k
Copy link
Contributor

deads2k commented May 18, 2017

@k8s-bot gce etcd3 e2e test this

return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
wantsCompression, encoding := wantsCompressedResponse(req)
if wantsCompression {
compressionWriter := NewCompressionResponseWriter(w, encoding)
Copy link
Contributor

Choose a reason for hiding this comment

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

@sttts I remember that this caused us problems in the general case, but here it's only getting added for get and list. Any concerns about wrapping here?

Copy link
Contributor

Choose a reason for hiding this comment

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

looks good

@k8s-github-robot k8s-github-robot removed lgtm "Looks good to me", indicates that a PR is ready to be merged. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. labels Jun 3, 2017
@deads2k deads2k added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Jun 5, 2017
@deads2k
Copy link
Contributor

deads2k commented Jun 5, 2017

@k8s-bot pull-kubernetes-unit test this

@ilackarms
Copy link
Contributor Author

gating issue #46963

@liggitt
Copy link
Member

liggitt commented Jun 5, 2017

go ahead and add a release note in the PR description

@k8s-ci-robot
Copy link
Contributor

k8s-ci-robot commented Jun 5, 2017

@ilackarms: The following test failed, say /retest to rerun them all:

Test name Commit Details Rerun command
Jenkins GCE etcd3 e2e 20b37cb1e092c2ddeb9a872f6f8678562e91dc06 link @k8s-bot gce etcd3 e2e test this

Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

@k8s-github-robot k8s-github-robot removed the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jun 5, 2017
@deads2k deads2k added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jun 6, 2017
@deads2k
Copy link
Contributor

deads2k commented Jun 6, 2017

I updated links and issues, so this gets another shot in the queue. please update.

@k8s-github-robot k8s-github-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Jun 6, 2017
@deads2k deads2k added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Jun 6, 2017
@smarterclayton
Copy link
Contributor

Submit queue, pay attention.

@k8s-github-robot
Copy link

Automatic merge from submit-queue

@k8s-github-robot k8s-github-robot merged commit cc568f6 into kubernetes:master Jun 6, 2017
@ilackarms ilackarms deleted the compression branch June 6, 2017 15:01
k8s-github-robot pushed a commit that referenced this pull request Jun 23, 2017
Automatic merge from submit-queue (batch tested with PRs 47883, 47179, 46966, 47982, 47945)

Add feature gating to REST Compression

**What this PR does / why we need it**: Adds feature gating to opt out of REST API compression

**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #46963 

**Special notes for your reviewer**: This PR is a fix / addendum to #45666

**Release note**:

```release-note
```
@sppatel
Copy link

sppatel commented Aug 4, 2017

Does anyone know what version of kubernetes this made it into? I'm using minikube that contains 1.7..0 and setting the Accept-encoding to gzip but I do not see the expected Content-Encoding response header after requesting a resource list.

@ilackarms
Copy link
Contributor Author

@sppatel see #46966; this PR was reverted in favor of that one. I'm not sure which version it was merged into, but in that PR, compression is disabled by default. In order to enable it, you'll need to use the feature flag APIResponseCompression

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.