use of io.grpc.LoadBalancer.SubchannelPicker in project grpc-java by grpc.
the class GracefulSwitchLoadBalancerTest method switchWhileOldPolicyGoesFromReadyToNotReadyWhileNewPolicyStillIdle.
@Test
public void switchWhileOldPolicyGoesFromReadyToNotReadyWhileNewPolicyStillIdle() {
gracefulSwitchLb.switchTo(lbProviders.get(lbPolicies[0]));
LoadBalancer lb0 = balancers.get(lbPolicies[0]);
InOrder inOrder = inOrder(lb0, mockHelper);
Helper helper0 = helpers.get(lb0);
SubchannelPicker picker = mock(SubchannelPicker.class);
helper0.updateBalancingState(READY, picker);
gracefulSwitchLb.switchTo(lbProviders.get(lbPolicies[1]));
verify(lb0, never()).shutdown();
LoadBalancer lb1 = balancers.get(lbPolicies[1]);
Helper helper1 = helpers.get(lb1);
picker = mock(SubchannelPicker.class);
helper0.updateBalancingState(CONNECTING, picker);
verify(mockHelper, never()).updateBalancingState(CONNECTING, picker);
inOrder.verify(mockHelper).updateBalancingState(CONNECTING, BUFFER_PICKER);
// shutdown after update
inOrder.verify(lb0).shutdown();
picker = mock(SubchannelPicker.class);
helper1.updateBalancingState(CONNECTING, picker);
inOrder.verify(mockHelper).updateBalancingState(CONNECTING, picker);
inOrder.verifyNoMoreInteractions();
verifyNoMoreInteractions(lb1);
}
use of io.grpc.LoadBalancer.SubchannelPicker in project grpc-java by grpc.
the class PickFirstLoadBalancerTest method requestConnectionPicker.
@Test
public void requestConnectionPicker() throws Exception {
loadBalancer.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(servers).setAttributes(affinity).build());
InOrder inOrder = inOrder(mockHelper, mockSubchannel);
inOrder.verify(mockSubchannel).start(stateListenerCaptor.capture());
SubchannelStateListener stateListener = stateListenerCaptor.getValue();
inOrder.verify(mockHelper).updateBalancingState(eq(CONNECTING), any(SubchannelPicker.class));
inOrder.verify(mockSubchannel).requestConnection();
stateListener.onSubchannelState(ConnectivityStateInfo.forNonError(IDLE));
inOrder.verify(mockHelper).updateBalancingState(eq(IDLE), pickerCaptor.capture());
SubchannelPicker picker = pickerCaptor.getValue();
// Calling pickSubchannel() twice gave the same result
assertEquals(picker.pickSubchannel(mockArgs), picker.pickSubchannel(mockArgs));
// But the picker calls requestConnection() only once
inOrder.verify(mockSubchannel).requestConnection();
verify(mockSubchannel, times(2)).requestConnection();
}
use of io.grpc.LoadBalancer.SubchannelPicker in project grpc-java by grpc.
the class PriorityLoadBalancerTest method typicalPriorityFailOverFlow.
@Test
public void typicalPriorityFailOverFlow() {
PriorityChildConfig priorityChildConfig0 = new PriorityChildConfig(new PolicySelection(fooLbProvider, new Object()), true);
PriorityChildConfig priorityChildConfig1 = new PriorityChildConfig(new PolicySelection(fooLbProvider, new Object()), true);
PriorityChildConfig priorityChildConfig2 = new PriorityChildConfig(new PolicySelection(fooLbProvider, new Object()), true);
PriorityChildConfig priorityChildConfig3 = new PriorityChildConfig(new PolicySelection(fooLbProvider, new Object()), true);
PriorityLbConfig priorityLbConfig = new PriorityLbConfig(ImmutableMap.of("p0", priorityChildConfig0, "p1", priorityChildConfig1, "p2", priorityChildConfig2, "p3", priorityChildConfig3), ImmutableList.of("p0", "p1", "p2", "p3"));
priorityLb.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(ImmutableList.<EquivalentAddressGroup>of()).setLoadBalancingPolicyConfig(priorityLbConfig).build());
assertThat(fooBalancers).hasSize(1);
assertThat(fooHelpers).hasSize(1);
LoadBalancer balancer0 = Iterables.getLast(fooBalancers);
Helper helper0 = Iterables.getOnlyElement(fooHelpers);
// p0 gets READY.
final Subchannel subchannel0 = mock(Subchannel.class);
helper0.updateBalancingState(READY, new SubchannelPicker() {
@Override
public PickResult pickSubchannel(PickSubchannelArgs args) {
return PickResult.withSubchannel(subchannel0);
}
});
assertCurrentPickerPicksSubchannel(subchannel0);
// p0 fails over to p1 immediately.
helper0.updateBalancingState(TRANSIENT_FAILURE, new ErrorPicker(Status.ABORTED));
assertLatestConnectivityState(CONNECTING);
assertThat(fooBalancers).hasSize(2);
assertThat(fooHelpers).hasSize(2);
LoadBalancer balancer1 = Iterables.getLast(fooBalancers);
// p1 timeout, and fails over to p2
fakeClock.forwardTime(10, TimeUnit.SECONDS);
assertLatestConnectivityState(CONNECTING);
assertThat(fooBalancers).hasSize(3);
assertThat(fooHelpers).hasSize(3);
LoadBalancer balancer2 = Iterables.getLast(fooBalancers);
Helper helper2 = Iterables.getLast(fooHelpers);
// p2 gets READY
final Subchannel subchannel1 = mock(Subchannel.class);
helper2.updateBalancingState(READY, new SubchannelPicker() {
@Override
public PickResult pickSubchannel(PickSubchannelArgs args) {
return PickResult.withSubchannel(subchannel1);
}
});
assertCurrentPickerPicksSubchannel(subchannel1);
// p0 gets back to READY
final Subchannel subchannel2 = mock(Subchannel.class);
helper0.updateBalancingState(READY, new SubchannelPicker() {
@Override
public PickResult pickSubchannel(PickSubchannelArgs args) {
return PickResult.withSubchannel(subchannel2);
}
});
assertCurrentPickerPicksSubchannel(subchannel2);
// p2 fails but does not affect overall picker
helper2.updateBalancingState(TRANSIENT_FAILURE, new ErrorPicker(Status.UNAVAILABLE));
assertCurrentPickerPicksSubchannel(subchannel2);
// p0 fails over to p3 immediately since p1 already timeout and p2 already in TRANSIENT_FAILURE.
helper0.updateBalancingState(TRANSIENT_FAILURE, new ErrorPicker(Status.UNAVAILABLE));
assertLatestConnectivityState(CONNECTING);
assertThat(fooBalancers).hasSize(4);
assertThat(fooHelpers).hasSize(4);
LoadBalancer balancer3 = Iterables.getLast(fooBalancers);
Helper helper3 = Iterables.getLast(fooHelpers);
// p3 timeout then the channel should go to TRANSIENT_FAILURE
fakeClock.forwardTime(10, TimeUnit.SECONDS);
assertCurrentPickerReturnsError(Status.Code.UNAVAILABLE, "timeout");
// p3 fails then the picker should have error status updated
helper3.updateBalancingState(TRANSIENT_FAILURE, new ErrorPicker(Status.DATA_LOSS.withDescription("foo")));
assertCurrentPickerReturnsError(Status.Code.DATA_LOSS, "foo");
// p2 gets back to READY
final Subchannel subchannel3 = mock(Subchannel.class);
helper2.updateBalancingState(READY, new SubchannelPicker() {
@Override
public PickResult pickSubchannel(PickSubchannelArgs args) {
return PickResult.withSubchannel(subchannel3);
}
});
assertCurrentPickerPicksSubchannel(subchannel3);
// p0 gets back to READY
final Subchannel subchannel4 = mock(Subchannel.class);
helper0.updateBalancingState(READY, new SubchannelPicker() {
@Override
public PickResult pickSubchannel(PickSubchannelArgs args) {
return PickResult.withSubchannel(subchannel4);
}
});
assertCurrentPickerPicksSubchannel(subchannel4);
// p0 fails over to p2 and picker is updated to p2's existing picker.
helper0.updateBalancingState(TRANSIENT_FAILURE, new ErrorPicker(Status.UNAVAILABLE));
assertCurrentPickerPicksSubchannel(subchannel3);
// Deactivate child balancer get deleted.
fakeClock.forwardTime(15, TimeUnit.MINUTES);
verify(balancer0, never()).shutdown();
verify(balancer1, never()).shutdown();
verify(balancer2, never()).shutdown();
verify(balancer3).shutdown();
}
use of io.grpc.LoadBalancer.SubchannelPicker in project grpc-java by grpc.
the class ClusterManagerLoadBalancerTest method updateBalancingStateFromChildBalancers.
@Test
public void updateBalancingStateFromChildBalancers() {
deliverResolvedAddresses(ImmutableMap.of("childA", "policy_a", "childB", "policy_b"));
assertThat(childBalancers).hasSize(2);
FakeLoadBalancer childBalancer1 = childBalancers.get(0);
FakeLoadBalancer childBalancer2 = childBalancers.get(1);
Subchannel subchannel1 = mock(Subchannel.class);
Subchannel subchannel2 = mock(Subchannel.class);
childBalancer1.deliverSubchannelState(subchannel1, ConnectivityState.READY);
verify(helper).updateBalancingState(eq(ConnectivityState.READY), pickerCaptor.capture());
SubchannelPicker picker = pickerCaptor.getValue();
assertThat(pickSubchannel(picker, "childA").getSubchannel()).isEqualTo(subchannel1);
assertThat(pickSubchannel(picker, "childB")).isEqualTo(PickResult.withNoResult());
childBalancer2.deliverSubchannelState(subchannel2, ConnectivityState.READY);
verify(helper, times(2)).updateBalancingState(eq(ConnectivityState.READY), pickerCaptor.capture());
assertThat(pickSubchannel(pickerCaptor.getValue(), "childB").getSubchannel()).isEqualTo(subchannel2);
}
use of io.grpc.LoadBalancer.SubchannelPicker in project grpc-java by grpc.
the class RingHashLoadBalancerTest method hostSelectionProportionalToRepeatedAddressCount.
@Test
public void hostSelectionProportionalToRepeatedAddressCount() {
RingHashConfig config = new RingHashConfig(10000, 100000);
// 1:10:100
List<EquivalentAddressGroup> servers = createRepeatedServerAddrs(1, 10, 100);
loadBalancer.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(servers).setLoadBalancingPolicyConfig(config).build());
verify(helper, times(3)).createSubchannel(any(CreateSubchannelArgs.class));
verify(helper).updateBalancingState(eq(IDLE), any(SubchannelPicker.class));
// Bring all subchannels to READY.
Map<EquivalentAddressGroup, Integer> pickCounts = new HashMap<>();
for (Subchannel subchannel : subchannels.values()) {
deliverSubchannelState(subchannel, ConnectivityStateInfo.forNonError(READY));
pickCounts.put(subchannel.getAddresses(), 0);
}
verify(helper, times(3)).updateBalancingState(eq(READY), pickerCaptor.capture());
SubchannelPicker picker = pickerCaptor.getValue();
for (int i = 0; i < 10000; i++) {
long hash = hashFunc.hashInt(i);
PickSubchannelArgs args = new PickSubchannelArgsImpl(TestMethodDescriptors.voidMethod(), new Metadata(), CallOptions.DEFAULT.withOption(XdsNameResolver.RPC_HASH_KEY, hash));
Subchannel pickedSubchannel = picker.pickSubchannel(args).getSubchannel();
EquivalentAddressGroup addr = pickedSubchannel.getAddresses();
pickCounts.put(addr, pickCounts.get(addr) + 1);
}
// Actual distribution: server0 = 104, server1 = 808, server2 = 9088
double ratio01 = (double) pickCounts.get(servers.get(0)) / pickCounts.get(servers.get(1));
double ratio12 = (double) pickCounts.get(servers.get(1)) / pickCounts.get(servers.get(11));
assertThat(ratio01).isWithin(0.03).of((double) 1 / 10);
assertThat(ratio12).isWithin(0.03).of((double) 10 / 100);
}
Aggregations