22
22
23
23
import com .google .common .annotations .VisibleForTesting ;
24
24
import com .google .common .base .MoreObjects ;
25
+ import io .grpc .ChannelLogger .ChannelLogLevel ;
25
26
import io .grpc .ConnectivityState ;
27
+ import io .grpc .LoadBalancer ;
26
28
import io .grpc .LoadBalancer .Helper ;
27
29
import io .grpc .LoadBalancer .Subchannel ;
28
30
import io .grpc .LoadBalancer .SubchannelPicker ;
29
31
import io .grpc .LoadBalancerProvider ;
30
32
import io .grpc .LoadBalancerRegistry ;
33
+ import io .grpc .NameResolver .ConfigOrError ;
31
34
import io .grpc .internal .ObjectPool ;
32
35
import io .grpc .rls .ChildLoadBalancerHelper .ChildLoadBalancerHelperProvider ;
33
36
import io .grpc .rls .RlsProtoData .RouteLookupConfig ;
@@ -191,33 +194,49 @@ public String toString() {
191
194
192
195
/** Factory for {@link ChildPolicyWrapper}. */
193
196
static final class RefCountedChildPolicyWrapperFactory {
197
+ // GuardedBy CachingRlsLbClient.lock
194
198
@ VisibleForTesting
195
199
final Map <String /* target */ , RefCountedChildPolicyWrapper > childPolicyMap =
196
200
new HashMap <>();
197
201
198
202
private final ChildLoadBalancerHelperProvider childLbHelperProvider ;
199
203
private final ChildLbStatusListener childLbStatusListener ;
204
+ private final ChildLoadBalancingPolicy childPolicy ;
205
+ private final ResolvedAddressFactory childLbResolvedAddressFactory ;
200
206
201
207
public RefCountedChildPolicyWrapperFactory (
208
+ ChildLoadBalancingPolicy childPolicy ,
209
+ ResolvedAddressFactory childLbResolvedAddressFactory ,
202
210
ChildLoadBalancerHelperProvider childLbHelperProvider ,
203
211
ChildLbStatusListener childLbStatusListener ) {
212
+ this .childPolicy = checkNotNull (childPolicy , "childPolicy" );
213
+ this .childLbResolvedAddressFactory =
214
+ checkNotNull (childLbResolvedAddressFactory , "childLbResolvedAddressFactory" );
204
215
this .childLbHelperProvider = checkNotNull (childLbHelperProvider , "childLbHelperProvider" );
205
216
this .childLbStatusListener = checkNotNull (childLbStatusListener , "childLbStatusListener" );
206
217
}
207
218
219
+ // GuardedBy CachingRlsLbClient.lock
208
220
ChildPolicyWrapper createOrGet (String target ) {
209
221
// TODO(creamsoup) check if the target is valid or not
210
222
RefCountedChildPolicyWrapper pooledChildPolicyWrapper = childPolicyMap .get (target );
211
223
if (pooledChildPolicyWrapper == null ) {
212
- ChildPolicyWrapper childPolicyWrapper =
213
- new ChildPolicyWrapper (target , childLbHelperProvider , childLbStatusListener );
224
+ ChildPolicyWrapper childPolicyWrapper = new ChildPolicyWrapper (
225
+ target , childPolicy , childLbResolvedAddressFactory , childLbHelperProvider ,
226
+ childLbStatusListener );
214
227
pooledChildPolicyWrapper = RefCountedChildPolicyWrapper .of (childPolicyWrapper );
215
228
childPolicyMap .put (target , pooledChildPolicyWrapper );
229
+ return pooledChildPolicyWrapper .getObject ();
230
+ } else {
231
+ ChildPolicyWrapper childPolicyWrapper = pooledChildPolicyWrapper .getObject ();
232
+ if (childPolicyWrapper .getPicker () != null ) {
233
+ childPolicyWrapper .refreshState ();
234
+ }
235
+ return childPolicyWrapper ;
216
236
}
217
-
218
- return pooledChildPolicyWrapper .getObject ();
219
237
}
220
238
239
+ // GuardedBy CachingRlsLbClient.lock
221
240
void release (ChildPolicyWrapper childPolicyWrapper ) {
222
241
checkNotNull (childPolicyWrapper , "childPolicyWrapper" );
223
242
String target = childPolicyWrapper .getTarget ();
@@ -238,16 +257,36 @@ static final class ChildPolicyWrapper {
238
257
239
258
private final String target ;
240
259
private final ChildPolicyReportingHelper helper ;
260
+ private final LoadBalancer lb ;
241
261
private volatile SubchannelPicker picker ;
242
262
private ConnectivityState state ;
243
263
244
264
public ChildPolicyWrapper (
245
265
String target ,
266
+ ChildLoadBalancingPolicy childPolicy ,
267
+ final ResolvedAddressFactory childLbResolvedAddressFactory ,
246
268
ChildLoadBalancerHelperProvider childLbHelperProvider ,
247
269
ChildLbStatusListener childLbStatusListener ) {
248
270
this .target = target ;
249
271
this .helper =
250
272
new ChildPolicyReportingHelper (childLbHelperProvider , childLbStatusListener );
273
+ LoadBalancerProvider lbProvider = childPolicy .getEffectiveLbProvider ();
274
+ final ConfigOrError lbConfig =
275
+ lbProvider
276
+ .parseLoadBalancingPolicyConfig (
277
+ childPolicy .getEffectiveChildPolicy (target ));
278
+ this .lb = lbProvider .newLoadBalancer (helper );
279
+ helper .getChannelLogger ().log (
280
+ ChannelLogLevel .DEBUG , "RLS child lb created. config: {0}" , lbConfig .getConfig ());
281
+ helper .getSynchronizationContext ().execute (
282
+ new Runnable () {
283
+ @ Override
284
+ public void run () {
285
+ lb .handleResolvedAddresses (
286
+ childLbResolvedAddressFactory .create (lbConfig .getConfig ()));
287
+ lb .requestConnection ();
288
+ }
289
+ });
251
290
}
252
291
253
292
String getTarget () {
@@ -263,7 +302,25 @@ ChildPolicyReportingHelper getHelper() {
263
302
}
264
303
265
304
void refreshState () {
266
- helper .updateBalancingState (state , picker );
305
+ helper .getSynchronizationContext ().execute (
306
+ new Runnable () {
307
+ @ Override
308
+ public void run () {
309
+ helper .updateBalancingState (state , picker );
310
+ }
311
+ }
312
+ );
313
+ }
314
+
315
+ void shutdown () {
316
+ helper .getSynchronizationContext ().execute (
317
+ new Runnable () {
318
+ @ Override
319
+ public void run () {
320
+ lb .shutdown ();
321
+ }
322
+ }
323
+ );
267
324
}
268
325
269
326
@ Override
@@ -346,6 +403,7 @@ public ChildPolicyWrapper returnObject(Object object) {
346
403
long newCnt = refCnt .decrementAndGet ();
347
404
checkState (newCnt != -1 , "Cannot return never pooled childPolicyWrapper" );
348
405
if (newCnt == 0 ) {
406
+ childPolicyWrapper .shutdown ();
349
407
childPolicyWrapper = null ;
350
408
}
351
409
return null ;
0 commit comments