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

Remove call to proto.Clone() in http2Server.WriteStatus. #2842

Merged
merged 15 commits into from
Jun 10, 2019

Conversation

easwars
Copy link
Contributor

@easwars easwars commented May 30, 2019

Fixes #2182

  • Expose a method from the internal package to get to the raw
    StatusProto wrapped by the status error, and use it from
    http2Server.WriteStatus().
  • Add a helper method in internal/testutils to compare two status errors
    and update test code to use that instead of reflect.DeepEqual()

Update fork with changes from master
Move MinConnectionTimeout() out of backoff.Strategy interface. Store
it directly in dialOptions instead, and have ClientConn use it from
there.
I need to roll these back because I had sent out changes from my master
branch, and this is causing a lot of pain right now for my work on other
branches. I will create a branch for this issue and will send out these
changes in a fresh PR.
Sync fork with upstream master.
@easwars easwars requested review from menghanl and dfawley May 30, 2019 19:45
@dfawley
Copy link
Member

dfawley commented May 30, 2019

  • The go.mod and go.sum changes should be reverted from this PR.
  • Consider squashing all your commits down to 1 (or a small number if there are relevant discrete changes for one PR) before sending the first iteration of a PR. You can do this now and then git push -f your branch.
  • For best results, use git fetch upstream master && git rebase upstream/master to pull mainline commits into your branch when needed instead of using git merge.

easwars added a commit to easwars/grpc-go that referenced this pull request May 30, 2019
* Expose a method from the internal package to get to the raw
  StatusProto wrapped by the status error, and use it from
  http2Server.WriteStatus().
* Add a helper method in internal/testutils to compare two status errors
  and update test code to use that instead of reflect.DeepEqual()
@easwars
Copy link
Contributor Author

easwars commented May 30, 2019

  • The go.mod and go.sum changes should be reverted from this PR.
    This is done now.
  • Consider squashing all your commits down to 1 (or a small number if there are relevant discrete changes for one PR) before sending the first iteration of a PR. You can do this now and then git push -f your branch.
    I think I have squashed my three commits made as part of this PR now. From next time, will do a better job.
  • For best results, use git fetch upstream master && git rebase upstream/master to pull mainline commits into your branch when needed instead of using git merge.
    I'm guessing, this is for the future.

Thanks for the git tips. Definitely going to be useful moving forward.

@easwars
Copy link
Contributor Author

easwars commented May 30, 2019

  • The go.mod and go.sum changes should be reverted from this PR.

This is done now.

vet is failing because the reverted go.sum and go.mod changes? How do we usually handle this?

  • Consider squashing all your commits down to 1 (or a small number if there are relevant discrete changes for one PR) before sending the first iteration of a PR. You can do this now and then git push -f your branch.

I think I have squashed my three commits made as part of this PR now. From next time, will do a better job.

  • For best results, use git fetch upstream master && git rebase upstream/master to pull mainline commits into your branch when needed instead of using git merge.

I'm guessing, this is for the future.

Thanks for the git tips. Definitely going to be useful moving forward.

Copy link
Member

@dfawley dfawley left a comment

Choose a reason for hiding this comment

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

LGTM modulo the one small change requested.

@@ -817,7 +819,8 @@ func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error {
headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-status", Value: strconv.Itoa(int(st.Code()))})
headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-message", Value: encodeGrpcMessage(st.Message())})

if p := st.Proto(); p != nil && len(p.Details) > 0 {
srp := internal.StatusRawProto.(func(*status.Status) *spb.Status)
Copy link
Member

Choose a reason for hiding this comment

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

It should be (a tiny bit) better to declare this globally and avoid the type assertion every time status is written:

var statusRawProto = internal.StatusRawProto.(func(*status.Status) *spb.Status)

(Also it would fail at init time if the types are wrong, instead of runtime, which is also a win.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Thanks.

@dfawley
Copy link
Member

dfawley commented Jun 3, 2019

I also meant to request some performance metrics for this change - can you run a QPS-style workload (many concurrent, small RPCs) before/after and see if this makes much difference in performance / allocations? Benchmark results should be posted in the first PR comment. Thanks.

@easwars
Copy link
Contributor Author

easwars commented Jun 3, 2019

I ran a benchmark with 100 concurrent calls and req and resp sizes of 32 bytes. There doesn't seem to any significant change in performance.

Stream-traceMode_false-latency_0s-kbps_0-MTU_0-maxConcurrentCalls_100-reqSize_32B-respSize_32B-Compressor_off-Preloader_false
Title Before After Percentage
Bytes/op 1345 1346 0.07%
Allocs/op 32 32 0.00%
50 latency 223.788µs 227.003µs 1.44%
90 latency 288.836µs 290.117µs 0.44%

@dfawley
Copy link
Member

dfawley commented Jun 4, 2019

Interesting. Do we trust the allocation numbers? I would expect them to be lower (both count and size) since we are removing proto.Clone calls. Though the status protos are very small without any "details" additions, so I would expect very small gains. Would you mind modifying the benchmarks locally to include a large details message in the server's response status to see if we can coerce a noticeable performance delta out of the benchmarks?

@easwars
Copy link
Contributor Author

easwars commented Jun 4, 2019

I made a change to the server to return a status with details message.

When I used a details message of len 128, this was the result:
Title Before After Percentage
Bytes/op 14275 13979 -2.07%
Allocs/op 170 166 -2.35%

And when I used a details message of len 512, this was the result:
Title Before After Percentage
Bytes/op 17961 17281 -3.79%
Allocs/op 172 168 -2.33%

The allocation numbers seem to be reasonably trustworthy in the sense that the number of allocs/op has not changed based on the length of the details message while the bytes/op has (and is proportional in some sense to the length of the details message).

@easwars
Copy link
Contributor Author

easwars commented Jun 5, 2019

@dfawley : Is there a way to get the vet test to be happy without the go.mod and go.sum changes?

package testutils

import (
"github.com/gogo/protobuf/proto"
Copy link
Member

Choose a reason for hiding this comment

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

This should not use gogo/proto

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Thanks.
Some of the tests are unusually flaky today. Unable to make travis happy as of now.

@easwars easwars merged commit a5396fd into grpc:master Jun 10, 2019
@dfawley dfawley added the Type: Performance Performance improvements (CPU, network, memory, etc) label Jun 13, 2019
@dfawley dfawley added this to the 1.22 Release milestone Jun 13, 2019
@easwars easwars deleted the status branch November 20, 2019 17:11
@lock lock bot locked as resolved and limited conversation to collaborators May 20, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Type: Performance Performance improvements (CPU, network, memory, etc)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Wasted proto.Clone in http2Server.WriteStatus
2 participants