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

grpcutil: new+fast FromIncomingContext variant #96318

Merged
merged 1 commit into from
Feb 3, 2023

Conversation

knz
Copy link
Contributor

@knz knz commented Jan 31, 2023

If we want to properly leverage gRPC metadata, we need to find a way
around the fact that the default metatada.FromIncomingContext is
slow and expensive. This patch fixes it.

BenchmarkFromIncomingContext/stdlib-32          10987958               327.5 ns/op           432 B/op          3 allocs/op
BenchmarkFromIncomingContext/fast-32            698772889                5.152 ns/op           0 B/op          0 allocs/op

Epic: None

@knz knz requested a review from andreimatei January 31, 2023 23:24
@knz
Copy link
Contributor Author

knz commented Jan 31, 2023

@andreimatei for your consideration.

@cockroach-teamcity
Copy link
Member

This change is Reviewable

@knz knz force-pushed the 20230201-fast-md branch from 7651228 to 8918602 Compare February 1, 2023 21:38
@knz knz marked this pull request as ready for review February 1, 2023 21:39
@knz knz requested a review from a team as a code owner February 1, 2023 21:39
@knz knz requested a review from a team February 1, 2023 21:39
@knz knz requested a review from a team as a code owner February 1, 2023 21:39
@knz knz requested review from a team and benbardin and removed request for a team February 1, 2023 21:39
@knz knz force-pushed the 20230201-fast-md branch 2 times, most recently from 92d72f0 to 44497dd Compare February 1, 2023 22:03
Copy link
Contributor

@andreimatei andreimatei left a comment

Choose a reason for hiding this comment

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

I like the functions that read the metadata without copying it.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @benbardin and @knz)


pkg/util/grpcutil/fast_metadata.go line 40 at r1 (raw file):

// from the given metadata key, if it exists. No extra objects are
// allocated. The key is assumed to contain only ASCII characters.
func FastFirstValueFromIncomingContext(ctx context.Context, key string) (bool, string) {

I think it's pretty broad convention for the bool return value to be the second one.


pkg/util/grpcutil/fast_metadata.go line 93 at r1 (raw file):

			newMd[k] = v
		}
		return found, val, context.WithValue(ctx, grpcIncomingKeyObj, newMd)

Is this context.WithValue() right? It looks to me like grpc wants a rawMD value, not a metadata.MD.
Why are we not using the vanillaNewOutgoingContext()?


pkg/util/grpcutil/fast_metadata.go line 132 at r1 (raw file):

type fakeContext struct {
	grpcIncomingKeyObj interface{}

Maybe call this recordedKey. Took me a second to get what's happening in this acid trip.


pkg/util/grpcutil/fast_metadata.go line 137 at r1 (raw file):

var _ context.Context = (*fakeContext)(nil)

func (f *fakeContext) Value(keyObj interface{}) interface{} {

lolo you gotta put a comment on this hack


pkg/util/grpcutil/fast_metadata.go line 31 at r2 (raw file):

//   - The caller promises to not modify the returned MD -- the gRPC
//     APIs assume that the map in the context remains constant.
func FastFromIncomingContext(ctx context.Context) (metadata.MD, bool) {

wanna use this in grpc_interceptor.go?


pkg/util/grpcutil/fast_metadata.go line 74 at r2 (raw file):

// from the given metadata key, if it exists. If it does, the metadata
// key is removed from the context.
func FastGetAndDeleteValueFromIncomingContext(

I'd say let's wait to introduce this one when it's actually used. I don't know if you can actually get this to work - see the comment below.

But beyond than that, the more I look around, the more I think that we should not be blindly forwarding random metadata. For the tracing metadata, I think it's rather a bad thing that we propagate it - when A calls B call C, we don't want C's span to be tied to A's span; I think that do more harm than good. In practice B will override the span ID (although it gets real funky in some edge cases). I also looked at the use of metadata in the blob service. That one is a pretty ridiculous use of metadata, but I'm sure it doesn't care about any forwarding. And generally, I think the next unsuspecting user of metadata will also not expect or want this magic propagation (which is only done for some RPCs, btw).
So I really think we should switch to propagating the user name explicitly. I can't imagine anything falling out of it.

@knz knz force-pushed the 20230201-fast-md branch from 44497dd to 297b948 Compare February 2, 2023 23:00
Copy link
Contributor Author

@knz knz left a comment

Choose a reason for hiding this comment

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

RFAL

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @andreimatei and @benbardin)


pkg/util/grpcutil/fast_metadata.go line 40 at r1 (raw file):

Previously, andreimatei (Andrei Matei) wrote…

I think it's pretty broad convention for the bool return value to be the second one.

Done.


pkg/util/grpcutil/fast_metadata.go line 93 at r1 (raw file):

Previously, andreimatei (Andrei Matei) wrote…

Is this context.WithValue() right? It looks to me like grpc wants a rawMD value, not a metadata.MD.
Why are we not using the vanillaNewOutgoingContext()?

This is a NewIncomingContext variant, which uses metadata.MD, not OutgoingContext. But this is moot - i removed it.


pkg/util/grpcutil/fast_metadata.go line 132 at r1 (raw file):

Previously, andreimatei (Andrei Matei) wrote…

Maybe call this recordedKey. Took me a second to get what's happening in this acid trip.

Done.


pkg/util/grpcutil/fast_metadata.go line 137 at r1 (raw file):

Previously, andreimatei (Andrei Matei) wrote…

lolo you gotta put a comment on this hack

Done.


pkg/util/grpcutil/fast_metadata.go line 31 at r2 (raw file):

Previously, andreimatei (Andrei Matei) wrote…

wanna use this in grpc_interceptor.go?

Done.


pkg/util/grpcutil/fast_metadata.go line 74 at r2 (raw file):

Previously, andreimatei (Andrei Matei) wrote…

I'd say let's wait to introduce this one when it's actually used. I don't know if you can actually get this to work - see the comment below.

But beyond than that, the more I look around, the more I think that we should not be blindly forwarding random metadata. For the tracing metadata, I think it's rather a bad thing that we propagate it - when A calls B call C, we don't want C's span to be tied to A's span; I think that do more harm than good. In practice B will override the span ID (although it gets real funky in some edge cases). I also looked at the use of metadata in the blob service. That one is a pretty ridiculous use of metadata, but I'm sure it doesn't care about any forwarding. And generally, I think the next unsuspecting user of metadata will also not expect or want this magic propagation (which is only done for some RPCs, btw).
So I really think we should switch to propagating the user name explicitly. I can't imagine anything falling out of it.

I removed them. Let's continue this discussion on the other PRs/issues.

@knz knz requested a review from andreimatei February 2, 2023 23:00
@knz knz force-pushed the 20230201-fast-md branch from 297b948 to 4f75ada Compare February 2, 2023 23:23
If we want to properly leverage gRPC metadata, we need to find a way
around the fact that the default `metatada.FromIncomingContext` is
slow and expensive. This patch fixes it.

```
BenchmarkFromIncomingContext/stdlib-32          10987958               327.5 ns/op           432 B/op          3 allocs/op
BenchmarkFromIncomingContext/fast-32            698772889                5.152 ns/op           0 B/op          0 allocs/op
```

Release note: None
@knz knz force-pushed the 20230201-fast-md branch from 4f75ada to 4384a92 Compare February 2, 2023 23:30
Copy link
Contributor

@andreimatei andreimatei left a comment

Choose a reason for hiding this comment

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

:lgtm:

but I don't know what to do about your comment wrapping. Why is it hard to do what everybody else does?

Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @benbardin)

@knz
Copy link
Contributor Author

knz commented Feb 3, 2023

Why is it hard to do what everybody else does?

I'll look into it.

bors r=andreimatei

@craig
Copy link
Contributor

craig bot commented Feb 3, 2023

Build succeeded:

@craig craig bot merged commit cebffa1 into cockroachdb:master Feb 3, 2023
@knz knz deleted the 20230201-fast-md branch February 3, 2023 12:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants