Skip to content

grpc: Add a pointer of server to ctx passed into stats handler #6625

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

Closed
wants to merge 2 commits into from

Conversation

zasweq
Copy link
Contributor

@zasweq zasweq commented Sep 13, 2023

This PR adds a pointer to the grpc.Server into the context passed into the stats handler. It also adds an internal only helper on the server that returns whether a given method is registered or not. This will be used in OpenTelemetry instrumentation for security purposes with respect to the cardinality of the method attribute. Contains and is based on (and technically requires) #6624. The next step after these two PRs is to move the rest of the stats handler callouts to the gRPC layer, get registered methods plumbed client side, canoncalize Target() without breaking it and then the OpenTelemetry instrumentation itself :).

RELEASE NOTES: N/A

@zasweq zasweq requested a review from dfawley September 13, 2023 04:41
@zasweq zasweq added the Type: Internal Cleanup Refactors, etc label Sep 13, 2023
@zasweq zasweq added this to the 1.59 Release milestone Sep 13, 2023
@zasweq zasweq added Type: Feature New features or improvements in behavior and removed Type: Internal Cleanup Refactors, etc labels Sep 13, 2023
@@ -1920,6 +1960,24 @@ func (s *Server) getCodec(contentSubtype string) baseCodec {
return codec
}

// isRegisteredMethod returns whether the passed in method is registered as a
// method on the server.
func (s *Server) isRegisteredMethod(method string) bool {
Copy link
Member

Choose a reason for hiding this comment

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

As discussed offline this needs to be a "full method name", parsed accordingly, with both service & method included in the check.

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.

Comment on lines +1706 to +1707
// getServer gets the Server from the context.
func getServer(ctx context.Context) *Server {
Copy link
Member

Choose a reason for hiding this comment

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

serverFromContext please

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.

}

// setServer sets the Server in the context.
func setServer(ctx context.Context, server *Server) context.Context {
Copy link
Member

Choose a reason for hiding this comment

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

contextWithServer please

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.

Comment on lines +6559 to +6562
if registeredMethod := internal.IsRegisteredMethod.(func(*grpc.Server, string) bool)(server, "UnaryCall"); !registeredMethod {
shsa.errorCh.Send(errors.New("UnaryCall should be a registered method according to server"))
return ctx
}
Copy link
Member

Choose a reason for hiding this comment

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

A little more readable:

isRegistered := internal.IsRegisteredMethod.(func..etc..)
if !isRegistered(server, "UnaryCall) {
  // fail
}
// etc

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, great point. Switched.

@@ -6539,3 +6539,89 @@ func (s) TestRPCBlockingOnPickerStatsCall(t *testing.T) {
t.Fatalf("sh.pickerUpdated count: %v, want: %v", pickerUpdatedCount, 2)
}
}

type statsHandlerServerAssert struct {
Copy link
Member

Choose a reason for hiding this comment

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

Should we make a stub stats handler that works like our server, so the implementation relevant to the test can live inside the test itself?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure. I'm gonna switch this test to use this new util. However, I won't switch all the tests that I wrote that use stats handler components to use this, but if you want me to I can do that (probably as another PR). Any future tests I will write I'll use this stub type.

// Within the stats handler, asking the server whether unary or duplex method
// names are registered should return true, and any other query should return
// false.
func (s) TestStatsHandlerCallsServerIsRegisteredMethod(t *testing.T) {
Copy link
Member

Choose a reason for hiding this comment

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

Can you add this to a stats_test.go, or put it into the stats directory, or even in the root directory since it's actually testing grpc.Server functionality? This file is approaching 7k lines which is crazy.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Chose to put it in stats directory, since that is where we want this helper to be called.

@dfawley dfawley assigned zasweq and unassigned dfawley Sep 14, 2023
@ginayeh ginayeh modified the milestones: 1.59 Release, 1.60 Release Oct 5, 2023
@zasweq
Copy link
Contributor Author

zasweq commented Oct 12, 2023

Got to all your comments and made a new pr containing all your comments: #6724. Thanks for the pass.

@zasweq zasweq closed this Oct 12, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 10, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Type: Feature New features or improvements in behavior
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants