Skip to content

Commit 2adeff5

Browse files
authored
xds: refactor resource subscription implementation in XdsClient (#7458)
Introduce ResourceSubscriber for tracking the state of a single resource. Every time newly subscribing to some resource, a corresponding ResourceSubscriber is created. Note it does not control the resource discovery RPCs. It is still the XdsClient that sends RPCs for with all subscribed resource names for each type. A ResourceSubscriber can have the following states: - When the initial resource fetch timer (respTimer) is pending, the resource is under discovery, the resource data is unknown. Even if the XdsClient receives a response not containing the corresponding resource, it does not mean the resource is absent. We still need to wait until a response containing the resource data coming or the timer being fired. The timer is scheduled when the ResourceSubscriber is created. So the XdsClient should always create the corresponding ResourceSubscriber when it starts to subscribe a new resource. - If the resource fetch timer is not pending, we must know the existence of the resource data. If data field is set, it is the most recently received resource data (aka, cached entry). Otherwise, absent field is set to true, indicating the resource does not exist. The exceptional case is when the ADS stream is closed and in the retry backoff period. During that period, respTimer is cancelled and the resource existence may or may not be known. Once the backoff finishes, the XdsClient will reschedule the respTimer when it recreates the ADS stream and re-request all the resources. Watchers can be added to existing ResourceSubscribers. At the time the watcher is added, its callback will be invoked if we've already known the existence of the resource. Otherwise, the watcher will just sit there and wait data or absence to come in the future.
1 parent 950ec30 commit 2adeff5

File tree

3 files changed

+257
-330
lines changed

3 files changed

+257
-330
lines changed

xds/src/main/java/io/grpc/xds/XdsClient.java

+35-15
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ ConfigUpdate build() {
103103
}
104104
}
105105

106-
static final class LdsUpdate {
106+
static final class LdsUpdate implements ResourceUpdate {
107107
// Total number of nanoseconds to keep alive an HTTP request/response stream.
108108
private final long httpMaxStreamDurationNano;
109109
// The name of the route configuration to be used for RDS resource discovery.
@@ -134,6 +134,25 @@ List<VirtualHost> getVirtualHosts() {
134134
return virtualHosts;
135135
}
136136

137+
@Override
138+
public int hashCode() {
139+
return Objects.hash(httpMaxStreamDurationNano, rdsName, virtualHosts);
140+
}
141+
142+
@Override
143+
public boolean equals(Object o) {
144+
if (this == o) {
145+
return true;
146+
}
147+
if (o == null || getClass() != o.getClass()) {
148+
return false;
149+
}
150+
LdsUpdate that = (LdsUpdate) o;
151+
return Objects.equals(httpMaxStreamDurationNano, that.httpMaxStreamDurationNano)
152+
&& Objects.equals(rdsName, that.rdsName)
153+
&& Objects.equals(virtualHosts, that.virtualHosts);
154+
}
155+
137156
@Override
138157
public String toString() {
139158
ToStringHelper toStringHelper = MoreObjects.toStringHelper(this);
@@ -182,7 +201,7 @@ LdsUpdate build() {
182201
}
183202
}
184203

185-
static final class RdsUpdate {
204+
static final class RdsUpdate implements ResourceUpdate {
186205
// The list virtual hosts that make up the route table.
187206
private final List<VirtualHost> virtualHosts;
188207

@@ -206,7 +225,7 @@ public String toString() {
206225
}
207226
}
208227

209-
static final class CdsUpdate {
228+
static final class CdsUpdate implements ResourceUpdate {
210229
private final String clusterName;
211230
@Nullable
212231
private final String edsServiceName;
@@ -351,7 +370,7 @@ CdsUpdate build() {
351370
}
352371
}
353372

354-
static final class EdsUpdate {
373+
static final class EdsUpdate implements ResourceUpdate {
355374
private final String clusterName;
356375
private final Map<Locality, LocalityLbEndpoints> localityLbEndpointsMap;
357376
private final List<DropOverload> dropPolicies;
@@ -497,10 +516,13 @@ ListenerUpdate build() {
497516
}
498517
}
499518

519+
interface ResourceUpdate {
520+
}
521+
500522
/**
501523
* Watcher interface for a single requested xDS resource.
502524
*/
503-
private interface ResourceWatcher {
525+
interface ResourceWatcher {
504526

505527
/**
506528
* Called when the resource discovery RPC encounters some transient error.
@@ -523,6 +545,14 @@ interface RdsResourceWatcher extends ResourceWatcher {
523545
void onChanged(RdsUpdate update);
524546
}
525547

548+
interface CdsResourceWatcher extends ResourceWatcher {
549+
void onChanged(CdsUpdate update);
550+
}
551+
552+
interface EdsResourceWatcher extends ResourceWatcher {
553+
void onChanged(EdsUpdate update);
554+
}
555+
526556
/**
527557
* Config watcher interface. To be implemented by the xDS resolver.
528558
*/
@@ -535,16 +565,6 @@ interface ConfigWatcher extends ResourceWatcher {
535565
void onConfigChanged(ConfigUpdate update);
536566
}
537567

538-
interface CdsResourceWatcher extends ResourceWatcher {
539-
540-
void onChanged(CdsUpdate update);
541-
}
542-
543-
interface EdsResourceWatcher extends ResourceWatcher {
544-
545-
void onChanged(EdsUpdate update);
546-
}
547-
548568
/**
549569
* Listener watcher interface. To be used by {@link io.grpc.xds.internal.sds.XdsServerBuilder}.
550570
*/

0 commit comments

Comments
 (0)