@@ -151,6 +151,7 @@ public void uncaughtException(Thread t, Throwable e) {
151
151
private String rlsChannelOverriddenAuthority ;
152
152
153
153
private void setUpRlsLbClient () {
154
+ fakeThrottler .resetCounts ();
154
155
rlsLbClient =
155
156
CachingRlsLbClient .newBuilder ()
156
157
.setBackoffProvider (fakeBackoffProvider )
@@ -362,6 +363,8 @@ public void get_updatesLbState() throws Exception {
362
363
assertThat (pickResult .getStatus ().isOk ()).isTrue ();
363
364
assertThat (pickResult .getSubchannel ()).isNotNull ();
364
365
assertThat (headers .get (RLS_DATA_KEY )).isEqualTo ("header-rls-data-value" );
366
+ assertThat (fakeThrottler .getNumThrottled ()).isEqualTo (0 );
367
+ assertThat (fakeThrottler .getNumUnthrottled ()).isEqualTo (1 );
365
368
366
369
// move backoff further back to only test error behavior
367
370
fakeBackoffProvider .nextPolicy = createBackoffPolicy (100 , TimeUnit .MILLISECONDS );
@@ -388,6 +391,97 @@ public void get_updatesLbState() throws Exception {
388
391
CallOptions .DEFAULT ));
389
392
assertThat (pickResult .getStatus ().getCode ()).isEqualTo (Code .UNAVAILABLE );
390
393
assertThat (pickResult .getStatus ().getDescription ()).contains ("fallback not available" );
394
+ assertThat (fakeThrottler .getNumThrottled ()).isEqualTo (1 );
395
+ assertThat (fakeThrottler .getNumUnthrottled ()).isEqualTo (1 );
396
+ }
397
+
398
+ @ Test
399
+ public void get_withAdaptiveThrottler () throws Exception {
400
+ AdaptiveThrottler adaptiveThrottler =
401
+ new AdaptiveThrottler .Builder ()
402
+ .setHistorySeconds (1 )
403
+ .setRatioForAccepts (1.0f )
404
+ .setRequestsPadding (1 )
405
+ .setTicker (fakeClock .getTicker ())
406
+ .build ();
407
+
408
+ this .rlsLbClient =
409
+ CachingRlsLbClient .newBuilder ()
410
+ .setBackoffProvider (fakeBackoffProvider )
411
+ .setResolvedAddressesFactory (resolvedAddressFactory )
412
+ .setEvictionListener (evictionListener )
413
+ .setHelper (helper )
414
+ .setLbPolicyConfig (lbPolicyConfiguration )
415
+ .setThrottler (adaptiveThrottler )
416
+ .setTicker (fakeClock .getTicker ())
417
+ .build ();
418
+ InOrder inOrder = inOrder (helper );
419
+ RouteLookupRequest routeLookupRequest = RouteLookupRequest .create (ImmutableMap .of (
420
+ "server" , "bigtable.googleapis.com" , "service-key" , "service1" , "method-key" , "create" ));
421
+ rlsServerImpl .setLookupTable (
422
+ ImmutableMap .of (
423
+ routeLookupRequest ,
424
+ RouteLookupResponse .create (
425
+ ImmutableList .of ("primary.cloudbigtable.googleapis.com" ),
426
+ "header-rls-data-value" )));
427
+
428
+ // valid channel
429
+ CachedRouteLookupResponse resp = getInSyncContext (routeLookupRequest );
430
+ assertThat (resp .isPending ()).isTrue ();
431
+ fakeClock .forwardTime (SERVER_LATENCY_MILLIS , TimeUnit .MILLISECONDS );
432
+
433
+ resp = getInSyncContext (routeLookupRequest );
434
+ assertThat (resp .hasData ()).isTrue ();
435
+
436
+ ArgumentCaptor <SubchannelPicker > pickerCaptor = ArgumentCaptor .forClass (SubchannelPicker .class );
437
+ ArgumentCaptor <ConnectivityState > stateCaptor =
438
+ ArgumentCaptor .forClass (ConnectivityState .class );
439
+ inOrder .verify (helper , times (2 ))
440
+ .updateBalancingState (stateCaptor .capture (), pickerCaptor .capture ());
441
+
442
+ Metadata headers = new Metadata ();
443
+ PickResult pickResult = pickerCaptor .getValue ().pickSubchannel (
444
+ new PickSubchannelArgsImpl (
445
+ TestMethodDescriptors .voidMethod ().toBuilder ().setFullMethodName ("service1/create" )
446
+ .build (),
447
+ headers ,
448
+ CallOptions .DEFAULT ));
449
+ assertThat (pickResult .getSubchannel ()).isNotNull ();
450
+ assertThat (headers .get (RLS_DATA_KEY )).isEqualTo ("header-rls-data-value" );
451
+
452
+ // move backoff further back to only test error behavior
453
+ fakeBackoffProvider .nextPolicy = createBackoffPolicy (100 , TimeUnit .MILLISECONDS );
454
+ // try to get invalid
455
+ RouteLookupRequest invalidRouteLookupRequest =
456
+ RouteLookupRequest .create (ImmutableMap .<String , String >of ());
457
+ CachedRouteLookupResponse errorResp = getInSyncContext (invalidRouteLookupRequest );
458
+ assertThat (errorResp .isPending ()).isTrue ();
459
+ fakeClock .forwardTime (SERVER_LATENCY_MILLIS , TimeUnit .MILLISECONDS );
460
+
461
+ errorResp = getInSyncContext (invalidRouteLookupRequest );
462
+ assertThat (errorResp .hasError ()).isTrue ();
463
+
464
+ // Channel is still READY because the subchannel for method /service1/create is still READY.
465
+ // Method /doesn/exists will use fallback child balancer and fail immediately.
466
+ inOrder .verify (helper )
467
+ .updateBalancingState (eq (ConnectivityState .READY ), pickerCaptor .capture ());
468
+ PickSubchannelArgsImpl invalidArgs = getInvalidArgs (headers );
469
+ pickResult = pickerCaptor .getValue ().pickSubchannel (invalidArgs );
470
+ assertThat (pickResult .getStatus ().getCode ()).isEqualTo (Code .UNAVAILABLE );
471
+ assertThat (pickResult .getStatus ().getDescription ()).contains ("fallback not available" );
472
+ long time = fakeClock .getTicker ().read ();
473
+ assertThat (adaptiveThrottler .requestStat .get (time )).isEqualTo (2L );
474
+ assertThat (adaptiveThrottler .throttledStat .get (time )).isEqualTo (1L );
475
+ }
476
+
477
+ private PickSubchannelArgsImpl getInvalidArgs (Metadata headers ) {
478
+ PickSubchannelArgsImpl invalidArgs = new PickSubchannelArgsImpl (
479
+ TestMethodDescriptors .voidMethod ().toBuilder ()
480
+ .setFullMethodName ("doesn/exists" )
481
+ .build (),
482
+ headers ,
483
+ CallOptions .DEFAULT );
484
+ return invalidArgs ;
391
485
}
392
486
393
487
@ Test
@@ -755,6 +849,8 @@ public ChannelLogger getChannelLogger() {
755
849
}
756
850
757
851
private static final class FakeThrottler implements Throttler {
852
+ int numUnthrottled ;
853
+ int numThrottled ;
758
854
759
855
private boolean nextResult = false ;
760
856
@@ -765,7 +861,24 @@ public boolean shouldThrottle() {
765
861
766
862
@ Override
767
863
public void registerBackendResponse (boolean throttled ) {
768
- // no-op
864
+ if (throttled ) {
865
+ numThrottled ++;
866
+ } else {
867
+ numUnthrottled ++;
868
+ }
869
+ }
870
+
871
+ public int getNumUnthrottled () {
872
+ return numUnthrottled ;
873
+ }
874
+
875
+ public int getNumThrottled () {
876
+ return numThrottled ;
877
+ }
878
+
879
+ public void resetCounts () {
880
+ numThrottled = 0 ;
881
+ numUnthrottled = 0 ;
769
882
}
770
883
}
771
884
}
0 commit comments