-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
base: master
Are you sure you want to change the base?
Conversation
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 shape looks fine.
xds/src/main/java/io/grpc/xds/XdsClusterSubscriptionRegistry.java
Outdated
Show resolved
Hide resolved
32c80c0
to
f995211
Compare
b7681c6
to
f5090ab
Compare
f5090ab
to
9fcbe4c
Compare
Ready for review @ejona86 |
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 still have a good amount to review. Sending what I have.
/** | ||
* Represents the xDS configuration tree for a specified Listener. | ||
*/ | ||
public class XdsConfig { |
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.
package-private final?
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
|
||
XdsConfig o = (XdsConfig) obj; | ||
|
||
return Objects.equals(listener, o.listener) && Objects.equals(route, o.route) |
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.
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.
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
StringBuilder builder = new StringBuilder(); | ||
builder.append("XdsConfig{listener=").append(listener) | ||
.append(", route=").append(route) | ||
.append(", clusters={").append(clusters).append("}}"); |
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.
clusters.toString()
will include the {}
.
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
@@ -136,7 +136,7 @@ protected RdsUpdate doParse(XdsResourceType.Args args, Message unpackedMessage) | |||
(RouteConfiguration) unpackedMessage, FilterRegistry.getDefaultRegistry(), args); | |||
} | |||
|
|||
private static RdsUpdate processRouteConfiguration( | |||
static RdsUpdate processRouteConfiguration( |
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.
Why remove the private
instead of calling doParse(args, routeConfiguration)
?
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.
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() { |
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.
Why aren't the fields private
if there are getters?
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.
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) { |
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.
|| !subscriptions.remove(subscription)
, since that is a common "already released" case?
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
private final XdsConfigWatcher xdsConfigWatcher; | ||
private final SynchronizationContext syncContext; | ||
private final String dataPlaneAuthority; | ||
private final Map<String, Set<ClusterSubscription>> clusterSubscriptions = new HashMap<>(); |
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 see any synchronization for mutations to this map, or requirements placed on the callers.
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.
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); |
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.
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.
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 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); |
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 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.
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.
Removed the syncContext from inside maybePublishConfig()
and do this methods logic in the syncContext.
} | ||
|
||
typeWatchers.add(resourceName, watcher); | ||
xdsClient.watchXdsResource(type, resourceName, watcher); |
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.
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.
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
…ds aggregate and eds entries.
This is just defining the XdsDependencyManager and associated classes; no movement of any functionality.