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

[RSDK-8291] Use Global Connection to App in Config Watcher #4773

Merged
merged 25 commits into from
Feb 7, 2025

Conversation

bashar-515
Copy link
Member

@bashar-515 bashar-515 commented Feb 5, 2025

This PR propagates the global connection to App that's instantiated in viam-server's entrypoint down to the function actually used by the config watcher to retrieve a new config. Before, this function would create and manage its own connection to App. Now, it receives a preexisting connection as a function parameter. The changes made here resulted in many modified function signatures, so lots of tests had to be edited to pass a connection even if not ultimately used (i.e., a config is being retrieved locally). In these test files, I simply pass in an empty &grpc.AppConn{}. This suffices because, again, the connection does not get used in the code path used by the test. In the few instances that it is used (usually when a mock server is spun up to deliver the config), I use the proper AppConn constructor and defer its closing.

For what's its worth, I've gone through the PR and marked the actual core functionality changes (i.e., not the test changes that are a mere side effect).

Testing RDK successfully reconfigures after config update following various combinations of connecting to/disconnecting from the internet.

@viambot viambot added the safe to test This pull request is marked safe to test from a trusted zone label Feb 5, 2025
@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Feb 5, 2025
@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Feb 5, 2025
@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Feb 5, 2025
@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Feb 5, 2025
@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Feb 6, 2025
@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Feb 6, 2025
@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Feb 6, 2025
@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Feb 6, 2025
@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Feb 6, 2025
@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Feb 6, 2025
@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Feb 6, 2025
Copy link
Member Author

Choose a reason for hiding this comment

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

core change

Copy link
Member Author

Choose a reason for hiding this comment

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

core change

Copy link
Member

Choose a reason for hiding this comment

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

Why is this file a "core change"? Is it because it's part of the "passing down" of the global app conn to config watching? Whereas other files are test changes?

Copy link
Member Author

Choose a reason for hiding this comment

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

ya sorry should've been more clear, you're right it's just a "non-test" change

Copy link
Member Author

Choose a reason for hiding this comment

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

refactor mentioned earlier

Copy link
Member

@benjirewis benjirewis left a comment

Choose a reason for hiding this comment

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

Nice! I've missed the PRs before this one, so may be commenting on pre-existing/already accepted patterns. Ignore my comments in that case.

@@ -45,7 +46,8 @@ func writeTempConfig(cfg *config.Config) (string, error) {
// make a fake robot with a vision service.
func buildRobotWithFakeCamera(logger logging.Logger) (robot.Robot, error) {
// add a fake camera to the config
cfg, err := config.Read(context.Background(), artifact.MustPath("components/camera/transformpipeline/vision.json"), logger)
cfg, err := config.Read(context.Background(), artifact.MustPath("components/camera/transformpipeline/vision.json"), logger,
&grpc.AppConn{})
Copy link
Member

Choose a reason for hiding this comment

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

[nit] You might've used this pattern elsewhere, but I often see nil passed instead of an "empty" struct when we want to communicate to another function that we have no special object for that function to use and it should create its own. Hypothetically, I'd have a small preference for passing nil here and not &grpc.AppConn.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done! I like this I for some reason glossed over this as an option when trying to figure how to make it apparent that the code path followed by the tests with an empty connection struct didn't actually need/use the conn so I like this

Copy link
Member

Choose a reason for hiding this comment

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

Why is this file a "core change"? Is it because it's part of the "passing down" of the global app conn to config watching? Whereas other files are test changes?

@@ -23,8 +29,20 @@ const (
// TimeReceivedMetadataKey is optional metadata in the gRPC response header that correlates
// to the time right after the point cloud was captured.
TimeReceivedMetadataKey = "viam-time-received"

readTimeout = 5 * time.Second
Copy link
Member

Choose a reason for hiding this comment

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

Now that we've moved these three timeout variables to context utils to avoid the import cycle, I think we'll need a) a small sentence describing what "read" they're governing (config reading) and b) to rename the variables to make it more clear what "read" they're governing.

)

// ViamDotDir is the directory for Viam's cached files.
var ViamDotDir string
Copy link
Member

Choose a reason for hiding this comment

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

The config read timeout vars' presence in this package is acceptable IMO, but I don't love ViamDotDir being here. It's only barely related to context creation; do you have any ideas for a better location @cheukt ?

Copy link
Member

Choose a reason for hiding this comment

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

utils/env.go maybe? but ya, not an easy var to find a location for

Copy link
Member

Choose a reason for hiding this comment

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

Let's do utils/env.go if that SGTY @bashar-515 , I like that better. Thanks, @cheukt .

@@ -542,7 +542,7 @@ func (s *robotServer) serveWeb(ctx context.Context, cfg *config.Config) (err err
}()

// watch for and deliver changes to the robot
watcher, err := config.NewWatcher(ctx, cfg, s.logger.Sublogger("config"))
watcher, err := config.NewWatcher(ctx, cfg, s.logger.Sublogger("config"), s.conn) // TODO(bashar)
Copy link
Member

Choose a reason for hiding this comment

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

TODO(bashar)

Is this not correct as it is?

@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Feb 6, 2025
@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Feb 6, 2025
@viambot viambot added safe to test This pull request is marked safe to test from a trusted zone and removed safe to test This pull request is marked safe to test from a trusted zone labels Feb 6, 2025
@bashar-515 bashar-515 requested a review from benjirewis February 6, 2025 21:34
Copy link
Member

@benjirewis benjirewis left a comment

Choose a reason for hiding this comment

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

LGTM! Thanks for the quick edits. Just one more q.

@@ -173,9 +173,11 @@ func RunServer(ctx context.Context, args []string, _ logging.Logger) (err error)
defer pprof.StopCPUProfile()
}

var appConn rpc.ClientConn
Copy link
Member

Choose a reason for hiding this comment

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

To clarify, appConn remains nil until a connection can be made to app yes? And, you're saying that all code paths you've seen do not try to call *appConn or appConn.foo without verifying that it's non-nil first?

@bashar-515
Copy link
Member Author

LGTM! Thanks for the quick edits. Just one more q.

Correct! appConn is initially nil until we read the local config that contains the info necessary to connect to App (the 'cloud' component of the config). In this case, calls can safely be made to the connection. If there isn't a cloud config, appConn remains nil. This is fine - as far as I've encountered - because all other consumers of the appConn also require a cloud config to exist before using/making calls to appConn. Now, appConn being nil is different from its underlying connection being nil. appConn itself can be non-nil, but it may have a nil underlying connection. This should also be okay bc calls to this underlying connection are protected by a nil check here.

Note this is re: your last question above for some reason github won't let me reply to it directly.

@bashar-515 bashar-515 merged commit edca01a into viamrobotics:main Feb 7, 2025
16 checks passed
@bashar-515 bashar-515 deleted the RSDK-8291 branch February 7, 2025 16:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
safe to test This pull request is marked safe to test from a trusted zone
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants