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

Add new classes for eliminating xds config tears #11740

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

larry-safran
Copy link
Contributor

@larry-safran larry-safran commented Dec 11, 2024

This is just defining the XdsDependencyManager and associated classes; no movement of any functionality.

@larry-safran larry-safran requested a review from ejona86 December 11, 2024 02:56
@larry-safran larry-safran marked this pull request as draft December 11, 2024 02:56
Copy link
Member

@ejona86 ejona86 left a comment

Choose a reason for hiding this comment

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

The shape looks fine.

Copy link

linux-foundation-easycla bot commented Jan 7, 2025

CLA Signed

The committers listed above are authorized under a signed CLA.

@larry-safran larry-safran marked this pull request as ready for review January 7, 2025 05:35
@larry-safran larry-safran requested a review from ejona86 January 7, 2025 05:35
@larry-safran
Copy link
Contributor Author

Ready for review @ejona86

Copy link
Member

@ejona86 ejona86 left a comment

Choose a reason for hiding this comment

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

I still have a good amount to review. Sending what I have.

/**
* Represents the xDS configuration tree for a specified Listener.
*/
public class XdsConfig {
Copy link
Member

Choose a reason for hiding this comment

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

package-private final?

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


XdsConfig o = (XdsConfig) obj;

return Objects.equals(listener, o.listener) && Objects.equals(route, o.route)
Copy link
Member

Choose a reason for hiding this comment

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

You probably want to include the hashCode and have it be the first equal check to short-circuit the more expensive stuff in the most common not-equals case.

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

StringBuilder builder = new StringBuilder();
builder.append("XdsConfig{listener=").append(listener)
.append(", route=").append(route)
.append(", clusters={").append(clusters).append("}}");
Copy link
Member

Choose a reason for hiding this comment

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

clusters.toString() will include the {}.

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

@@ -136,7 +136,7 @@ protected RdsUpdate doParse(XdsResourceType.Args args, Message unpackedMessage)
(RouteConfiguration) unpackedMessage, FilterRegistry.getDefaultRegistry(), args);
}

private static RdsUpdate processRouteConfiguration(
static RdsUpdate processRouteConfiguration(
Copy link
Member

Choose a reason for hiding this comment

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

Why remove the private instead of calling doParse(args, routeConfiguration)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. If you're curious, it was because type Message didn't sound like it was a data object and I didn't want to construct something just to parse it. Probably related to limit time interacting with protos.

return builder.toString();
}

public String getClusterName() {
Copy link
Member

Choose a reason for hiding this comment

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

Why aren't the fields private if there are getters?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Originally didn't have getters, but you are right they should be private.

checkNotNull(subscription, "subscription");
String clusterName = subscription.getClusterName();
Set<ClusterSubscription> subscriptions = clusterSubscriptions.get(clusterName);
if (subscriptions == null) {
Copy link
Member

Choose a reason for hiding this comment

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

|| !subscriptions.remove(subscription), since that is a common "already released" case?

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

private final XdsConfigWatcher xdsConfigWatcher;
private final SynchronizationContext syncContext;
private final String dataPlaneAuthority;
private final Map<String, Set<ClusterSubscription>> clusterSubscriptions = new HashMap<>();
Copy link
Member

Choose a reason for hiding this comment

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

I don't see any synchronization for mutations to this map, or requirements placed on the callers.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed so that now all updates and gets happen in syncContext. Verified all uses of both clusterSubscriptions and resourceWatchers are in the syncContext

case AGGREGATE:
for (String cluster : cdsUpdate.prioritizedClusterNames()) {
CdsWatcher clusterWatcher =
(CdsWatcher) resourceWatchers.get(CLUSTER_RESOURCE).watchers.get(cluster);
Copy link
Member

Choose a reason for hiding this comment

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

What if this cluster is used by another aggregate cluster or used directly by the route? I think that same sort of problem could exist for EDS. Just because it isn't any more by this cluster doesn't mean it isn't used any more.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought that clusters couldn't be in multiple aggregates. I started implementing a more complicated tracking of who was using a cluster, but believed that the situations you listed weren't allowed so kept it simple.

if (subscriptions.isEmpty()) {
clusterSubscriptions.remove(clusterName);
XdsWatcherBase<?> cdsWatcher =
resourceWatchers.get(CLUSTER_RESOURCE).watchers.get(clusterName);
Copy link
Member

Choose a reason for hiding this comment

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

This can only be accessed from the syncContext, right? This is not running in the syncContext.

The synchronization looks funny, especially with maybePublishConfig() entering the syncContext. It seems ever call to maybePublishConfig() would already need to be in the syncContext since that's the only way to change state.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the syncContext from inside maybePublishConfig() and do this methods logic in the syncContext.

}

typeWatchers.add(resourceName, watcher);
xdsClient.watchXdsResource(type, resourceName, watcher);
Copy link
Member

Choose a reason for hiding this comment

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

Use the 4-arg version, to pass in the executor to use (I assume syncContext). I think we would have deprecated/deleted this 3-arg version, but it is used a lot in tests. If you enter the syncContext manually within the callback, then ADS flow control stops working properly.

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants