-
Notifications
You must be signed in to change notification settings - Fork 67
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
Handle multiple services in generated http and tchannel clients #594
Handle multiple services in generated http and tchannel clients #594
Conversation
aeff8b7
to
4840882
Compare
runtime/client_http_request.go
Outdated
scopeTags := map[string]string{ | ||
scopeTagClientMethod: methodName, | ||
scopeTagClient: clientID, | ||
scopeTagClientService: serviceName, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The scopeTagClientService
tag, which is "clientservice", is a bit ambiguous as it doesn't differentiate between service name (as in service discovery) and Thrift service name. A better tag would be scopeTagsTargetEndpoint, whose value should be thrift service::method, e.g. Bar::helloWorld
. It would also align with TChannel client metrics tag.
To achieve that, we will need to pass in a thriftServiceMethod
parameter to the NewClientHTTPRequest
and adding the field to ClientHTTPRequest
. The downside of such change is slightly leaky abstraction as the client http request is now aware of the outer layer thrift service and method. A better alternative is that we move tag creation into generated code since all of the tags we add here are static info regarding the client and are available in the template.
But I am okay with either way because changing the signature isn't a really big deal since it is only used in the generated code.
@@ -53,17 +54,23 @@ type ClientHTTPRequest struct { | |||
// NewClientHTTPRequest allocates a ClientHTTPRequest. The ctx parameter is the context associated with the outbound requests. | |||
func NewClientHTTPRequest( | |||
ctx context.Context, | |||
clientID, methodName string, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The methodName
here is the Go method name of the corresponding client. We can keep it and introduce a new param thrfitServiceMethod
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was hoping to get away with not making a breaking change and rely on backwards compatibility. I just went ahead and made a breaking change as you suggested and passed the (thrift) service method names as another argument.
runtime/http_client.go
Outdated
@@ -54,7 +54,7 @@ func NewHTTPClient( | |||
logger *zap.Logger, | |||
scope tally.Scope, | |||
clientID string, | |||
methodNames []string, | |||
serviceMethodNames []string, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can change the param type form []string
to map[string]string
to capture both the Go method name of the client that user provides and its corresponding thrift service and method name.
runtime/client_http_request.go
Outdated
@@ -168,7 +175,7 @@ func (req *ClientHTTPRequest) WriteJSON( | |||
|
|||
// Do will send the request out. | |||
func (req *ClientHTTPRequest) Do() (*ClientHTTPResponse, error) { | |||
opName := fmt.Sprintf("%s.%s", req.ClientID, req.MethodName) | |||
opName := fmt.Sprintf("%s.%s", req.ServiceName, req.MethodName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we do change the client request struct, then ("%s.%s(%s)", req.ClientID, req.MethodName, req.ThriftServiceMethod)
might be a good alternative.
311a970
to
3132caa
Compare
runtime/http_client.go
Outdated
@@ -55,6 +55,7 @@ func NewHTTPClient( | |||
scope tally.Scope, | |||
clientID string, | |||
methodNames []string, | |||
targetEndpointNames []string, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes more sense to have a map, whose key is client method name and value is corresponding thrift serviceMethod, that replace both methodNames
and targetEndpointNames
. That is essentially what the user-provided exposedMethods is.
With that, the template change would be changing https://github.com/uber/zanzibar/blob/master/codegen/templates/http_client.tmpl#L103-L107 to
map[string]string{
{{range $serviceMethod, $methodName := $exposedMethods -}}
"{{$methodName}}": "{{$serviceMethod}}",
{{end}}
},
runtime/context.go
Outdated
scopeTagsTargetService = "targetservice" | ||
scopeTagsTargetEndpoint = "targetendpoint" | ||
scopeTagClientMethod = "clientmethod" | ||
scopeTagClientTargetEndpoint = "clienttargetendpoint" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is probably not necessary to introduce this new tag, scopeTagsTargetEndpoint
("targetendpoint") should be sufficient because of the existing contexts for the client operation. Also tchannel client and http client sharing this same tas make it easier when we query by tags.
@@ -102,7 +102,7 @@ func {{$exportName}}(deps *module.Dependencies) Client { | |||
{{$serviceMethod := printf "%s::%s" $svc.Name .Name -}} | |||
{{$methodName := (title (index $exposedMethods $serviceMethod)) -}} | |||
{{if $methodName -}} | |||
"{{$serviceMethod}}": "{{$methodName}}", | |||
"{{$serviceMethod}}": "{{title .Name}}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not be changed, the $methodName
is supposed to be the Go method name of the client.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the Edge Gateway usage of this template, there was always the assumption that the client and method names were a 1-1 mapping. Multiple services in one thrift disallow this. After talking offline with Chuntao offline, it sounds like we are going to just scrap the tchannel part of this diff and make consumers of metrics and logs switch to other metrics to avoid breaking changes in metrics and logging here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @abhishekparwal FYI
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the Edge Gateway usage of this template, there was always the assumption that the client and method names were a 1-1 mapping. Multiple services in one thrift disallow this. After talking offline with Chuntao offline, it sounds like we are going to just scrap the tchannel part of this diff and make consumers of metrics and logs switch to other metrics to avoid breaking changes in metrics and logging here.
To clarify, consumers of the metrics/logs will still look at the same metrics/logs but different tag/log field for thrift service and method. The client method name has always meant to be the Go method name of the client.
Co-Authored-By: skiptomylu <chuntaolu13@gmail.com>
Co-Authored-By: skiptomylu <chuntaolu13@gmail.com>
Co-Authored-By: skiptomylu <chuntaolu13@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, forgot suggesting the test changes. I have verified tests pass with these changes. You can also batch commit the suggestions thru the UI.
Co-Authored-By: skiptomylu <chuntaolu13@gmail.com>
Co-Authored-By: skiptomylu <chuntaolu13@gmail.com>
(Changed from previous version to reflect changes)
In this diff, we add a new parameter which is the client's target endpoint. For a thrift-based http client, this would be in the form of
ServiceName::methodName
. This is to provide support in metrics and logging for thrift files that define multiple services. Clients for such thrift files have cases where the client method name cannot match the thrift method name. Consider the following service definitions in one thrift file for a single client:Client method names cannot simply be the method name or we would have conflicting method names for the generated client struct. Thus, we must concatenate the service and method names to make this work. For example.
FooFn1
andBarFn1
.