-
Notifications
You must be signed in to change notification settings - Fork 111
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
RSDK-9818: Annotate gRPC requests from modules to the viam-server with module names. #4749
base: main
Are you sure you want to change the base?
Conversation
…h module names. Pass a VIAM_MODULE_NAME env variable to module processes.
@@ -43,3 +44,60 @@ func EnsureTimeoutUnaryClientInterceptor( | |||
|
|||
return invoker(ctx, method, req, reply, cc, opts...) | |||
} | |||
|
|||
// The following code is for appending/extracting grpc metadata regarding module names/origins via |
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.
Shoving this all inside of grpc/interceptors.go
seemed like a good spot, but open to alternatives. At first I tried inside the robot web server or modules directory (can't remember), but hit go import cycles.
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 file seems like the appropriate place IMO.
// Modules compiled against newer SDKs may be running against older `viam-server`s that do not | ||
// provide the module name as an env variable. | ||
if m.name != "" { | ||
connectOptions = append(connectOptions, client.WithModName(m.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.
I can go back to the chaining in the old code -- I thought it looked nicer.
I only did this to make checking for the empty string to be explicit. But in reality, the other end calling GetModuleName
copes with "old modules" by returning the empty string.
Maybe it'd be better for GetModuleName
to return an error -- I don't know!
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 don't have a strong opinion either way; I think what you have here is totally fine. GetModuleName
returning an error in the event of no module name on the metadata/context seems odd to me, though, given we expect to be interacting with older modules and inability to find the module name is not really an "error state."
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.
Looks pretty good; just some nits and questions.
@@ -43,3 +44,60 @@ func EnsureTimeoutUnaryClientInterceptor( | |||
|
|||
return invoker(ctx, method, req, reply, cc, opts...) | |||
} | |||
|
|||
// The following code is for appending/extracting grpc metadata regarding module names/origins via |
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 file seems like the appropriate place IMO.
} | ||
|
||
return handler(ctx, req) | ||
} |
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.
Do you not need Stream
versions of the interceptors? Or do we only care about unary for now?
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 only care about unary right now. I'm inclined to believe a stream would never need this? Or at least not in the in the same mold as we have here. I need to identify to module/connection such that I can use webrtc video streaming as opposed to a grpc stream.
But adding it couldn't hurt. Certainly would be surprising if one day someone did try using grabbing a module name from a stream request and failed to get it.
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 take this back -- streams don't have contexts. We play games to make that a thing. I'm inclined to punt for now.
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'm inclined to believe a stream would never need this?
Well we certainly don't have any gRPC streaming API between a module and rdk right now. Whether we never will: I'm not sure. I think punting is totally fine for now. I do remember looking at that ServerStreamContextWrapper
thing and scratching my head... I guess we'd have to do that in the future if we ever need the same feature for streaming gRPC APIs module <-> rdk 🤷🏻 .
module/module.go
Outdated
@@ -175,6 +175,9 @@ type peerResourceState struct { | |||
|
|||
// Module represents an external resource module that services components/services. | |||
type Module struct { | |||
// The name of the module as per the robot config. |
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 name of the module as per the robot config. | |
// The name of the module as indicated by `VIAM_MODULE_NAME`. |
I realize it is the name from the config, but nice to note that it's derived from the env var?
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 where the name comes from is more important than how it gets here (from a holistic point of view). But it doesn't hurt to add that detail.
// Modules compiled against newer SDKs may be running against older `viam-server`s that do not | ||
// provide the module name as an env variable. | ||
if m.name != "" { | ||
connectOptions = append(connectOptions, client.WithModName(m.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.
I don't have a strong opinion either way; I think what you have here is totally fine. GetModuleName
returning an error in the event of no module name on the metadata/context seems odd to me, though, given we expect to be interacting with older modules and inability to find the module name is not really an "error state."
robot/client/client_options.go
Outdated
@@ -56,6 +58,14 @@ func newFuncRobotClientOption(f func(*robotClientOpts)) *funcRobotClientOption { | |||
} | |||
} | |||
|
|||
// WithModName attaches a unary interceptor that attaches the module name for each outgoing gRPC | |||
// request. |
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.
// request. | |
// request. Should only be used in Viam module library code. |
Don't really care about the wording of the messaging, but maybe just a line to indicate that Golang SDK users (not that there are many) shouldn't really touch this option.
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.
Done
"reading": 42, | ||
}, nil | ||
}, | ||
CloseFunc: func(ctx context.Context) error { |
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.
Surprised you need a no-op CloseFunc
; I assume you get a panic without this?
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 copied it from elsewhere. But that was my reasoning -- was that it existed to avoid a panic.
@@ -106,9 +107,21 @@ func mainWithArgs(ctx context.Context, args []string, logger logging.Logger) err | |||
func newHelper( | |||
ctx context.Context, deps resource.Dependencies, conf resource.Config, logger logging.Logger, | |||
) (resource.Resource, error) { | |||
var dependsOnSensor sensor.Sensor |
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.
[opt] Doesn't really matter, but generally I've seen FromDependencies
used instead of for
loop searches like the one you're doing.
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 made a change, but I feel there's still some awkwardness.
I think the trouble arises because this "helper" model is "schema-less". Most tests aren't creating this with dependencies (obviously as per needing this change). And if they did want dependencies, it's not clear they'd want a sensor one? I don't think there's really a way to make this dependency parsing usage for "helper" be forward compatible.
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.
Cool; yeah it's still awkward, sorry about that. What you have seems fine. I think you're right that if we wanted this to "look good" (and I don't really care too much since this is just testing code) we'd need a type for helper configs and probably an associated Validate
method.
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.
LGTM! Thanks 🫡
Pass a VIAM_MODULE_NAME env variable to module processes.