Skip to content

RSDK-10762 Add test for modular optional dependency cycles #5060

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

Merged
merged 3 commits into from
Jun 17, 2025

Conversation

benjirewis
Copy link
Member

@benjirewis benjirewis commented Jun 17, 2025

RSDK-10762

Adds a test for modular optional dependency cycles that ensures modular resources can optionally depend upon each other without any Reconfigure methods (using AlwaysRebuild).

@viambot viambot added the safe to test This pull request is marked safe to test from a trusted zone label Jun 17, 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 Jun 17, 2025
@@ -617,7 +617,7 @@ func (m *Module) ReconfigureResource(ctx context.Context, req *pb.ReconfigureRes
return nil, err
}

m.logger.Debugw("rebuilding", "name", conf.ResourceName())
m.logger.Debugw("rebuilding", "name", conf.ResourceName().String())
Copy link
Member Author

Choose a reason for hiding this comment

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

[drive-by] Structure-logging this resource name object resulted in

server.go:453: 2025-06-17T12:37:00.294-0400	DEBUG	optional-deps	module/module.go:620	rebuilding	{"nameError":"PANIC=interface conversion: map[string]interface {} is not fmt.Stringer: missing method String","log_ts":"2025-06-17T16:37:00.294Z"}

Just stringified for now. Was this an issue we were aware of, @dgottlieb ? I forget.

Copy link
Member

Choose a reason for hiding this comment

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

This is an issue we've seen. I thought this was fixed by either something Cheuk or Josh did. But I think this is due to the map[string]interface getting zap encoded over our log entry proto as a "string" type.

Such that the zap encoding code assumes its a fmt.Stringer here.

Copy link
Member Author

Choose a reason for hiding this comment

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

Gotcha. Filed https://viam.atlassian.net/browse/RSDK-11007 and will just String() it here for now.

if resource.IsMustRebuildError(err) {
r.Logger().CErrorw(
ctx,
"non-modular resource uses weak/optional dependencies but is missing a Reconfigure method",
Copy link
Member Author

Choose a reason for hiding this comment

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

New "helpful" log.

@benjirewis benjirewis requested review from dgottlieb and cheukt June 17, 2025 16:40
@benjirewis benjirewis marked this pull request as ready for review June 17, 2025 16:40
},
{
Name: mocName2.Name,
API: generic.API,
Copy link
Member

@dgottlieb dgottlieb Jun 17, 2025

Choose a reason for hiding this comment

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

Given we're on a path to removing API -- this isn't a critique, just a thought experiment for further understanding. And this is a pretty meaningless scenario.

So we're seeing that creating mocName2 does not reconfigure mocName (but the client handle on mocName presumably will start working under the hood).

If mocName2 were to change its API to say the motor API, would that cause a reconstruction/reconfigure of mocName? Or would mocName be left with a "stale"[1] client object?

[1] The underlying connection and resource name never changes. But the set of methods that could be called "does not update" when it theory it ought to.

Copy link
Member

@cheukt cheukt Jun 17, 2025

Choose a reason for hiding this comment

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

in the current state, I do think that mocName will get reconfigured if mocName2's API changes. mocName2 will get closed and then re-added, which should prompt mocName to get reconfigured as well. but not super high confidence

Copy link
Member Author

Choose a reason for hiding this comment

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

So we're seeing that creating mocName2 does not reconfigure mocName (but the client handle on mocName presumably will start working under the hood).

For the new test I've added, when we add moc2, moc will technically get rebuilt module-side (it has no reconfigure method but is able to reconstruct in response to a ReconfigureResourceRequest) and given a gRPC client to moc2. In its initial construction moc was given no gRPC client (deps was empty when passed to constructor). Similary, when moc is removed from the config, moc2 will get rebuilt to pass in no gRPC client (deps will be empty). So, I don't think any gRPC client "starts" or "stops" working under the hood with this test. Maybe I'm misunderstanding your statement here.

Copy link
Member

@dgottlieb dgottlieb Jun 17, 2025

Choose a reason for hiding this comment

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

Got it. So when having moc and adding moc2:

  • Construct moc2 with dep=[moc]
  • Close -> Construct moc with dep=[moc2]

And even though moc is recreated since moc2 had a handle, moc2 is not recreated. We depend on moc2s existing client object to be continue to be valid.

Copy link
Member Author

Choose a reason for hiding this comment

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

And even though moc is recreated since moc2 had a handle, moc2 is not recreated. We depend on moc2s existing client object to be continue to be valid.

That's exactly right (or is my hope), and I don't think the test even exercises that moc2s existing client object is still valid, so let me add some assertions there. All I test right now is that the client object is still set but not usable.

Copy link
Member Author

Choose a reason for hiding this comment

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

Added.

Copy link
Member

@cheukt cheukt left a comment

Choose a reason for hiding this comment

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

LGTM

@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 Jun 17, 2025
@benjirewis benjirewis merged commit bbc2724 into viamrobotics:main Jun 17, 2025
18 checks passed
@benjirewis benjirewis deleted the modular-optional-deps-cycle branch June 17, 2025 20:57
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