use of io.grpc.internal.PickSubchannelArgsImpl in project grpc-java by grpc.
the class RingHashLoadBalancerTest method skipFailingHosts_firstTwoHostsFailed_pickNextFirstReady.
@Test
public void skipFailingHosts_firstTwoHostsFailed_pickNextFirstReady() {
// Map each server address to exactly one ring entry.
RingHashConfig config = new RingHashConfig(3, 3);
List<EquivalentAddressGroup> servers = createWeightedServerAddrs(1, 1, 1);
loadBalancer.handleResolvedAddresses(ResolvedAddresses.newBuilder().setAddresses(servers).setLoadBalancingPolicyConfig(config).build());
verify(helper, times(3)).createSubchannel(any(CreateSubchannelArgs.class));
// initial IDLE
verify(helper).updateBalancingState(eq(IDLE), any(SubchannelPicker.class));
reset(helper);
// ring:
// "[FakeSocketAddress-server1]_0"
// "[FakeSocketAddress-server0]_0"
// "[FakeSocketAddress-server2]_0"
long rpcHash = hashFunc.hashAsciiString("[FakeSocketAddress-server0]_0");
PickSubchannelArgs args = new PickSubchannelArgsImpl(TestMethodDescriptors.voidMethod(), new Metadata(), CallOptions.DEFAULT.withOption(XdsNameResolver.RPC_HASH_KEY, rpcHash));
// Bring down server0 and server2 to force trying server1.
deliverSubchannelState(subchannels.get(Collections.singletonList(servers.get(0))), ConnectivityStateInfo.forTransientFailure(Status.UNAVAILABLE.withDescription("unreachable")));
deliverSubchannelState(subchannels.get(Collections.singletonList(servers.get(2))), ConnectivityStateInfo.forTransientFailure(Status.PERMISSION_DENIED.withDescription("permission denied")));
verify(helper).updateBalancingState(eq(TRANSIENT_FAILURE), pickerCaptor.capture());
verify(subchannels.get(Collections.singletonList(servers.get(1)))).requestConnection();
PickResult result = pickerCaptor.getValue().pickSubchannel(args);
// fail the RPC
assertThat(result.getStatus().isOk()).isFalse();
assertThat(result.getStatus().getCode()).isEqualTo(// with error status for the original server hit by hash
Code.UNAVAILABLE);
assertThat(result.getStatus().getDescription()).isEqualTo("unreachable");
verify(subchannels.get(Collections.singletonList(servers.get(1))), times(2)).requestConnection();
// Now connecting to server1.
deliverSubchannelState(subchannels.get(Collections.singletonList(servers.get(1))), ConnectivityStateInfo.forNonError(CONNECTING));
verify(helper, times(2)).updateBalancingState(eq(TRANSIENT_FAILURE), pickerCaptor.capture());
result = pickerCaptor.getValue().pickSubchannel(args);
// fail the RPC
assertThat(result.getStatus().isOk()).isFalse();
assertThat(result.getStatus().getCode()).isEqualTo(// with error status for the original server hit by hash
Code.UNAVAILABLE);
assertThat(result.getStatus().getDescription()).isEqualTo("unreachable");
// Simulate server1 becomes READY.
deliverSubchannelState(subchannels.get(Collections.singletonList(servers.get(1))), ConnectivityStateInfo.forNonError(READY));
verify(helper).updateBalancingState(eq(READY), pickerCaptor.capture());
result = pickerCaptor.getValue().pickSubchannel(args);
// succeed
assertThat(result.getStatus().isOk()).isTrue();
// with server1
assertThat(result.getSubchannel().getAddresses()).isEqualTo(servers.get(1));
}
use of io.grpc.internal.PickSubchannelArgsImpl in project grpc-java by grpc.
the class XdsNameResolverTest method retryPolicyInPerMethodConfigGeneratedByResolverIsValid.
@Test
public void retryPolicyInPerMethodConfigGeneratedByResolverIsValid() {
ServiceConfigParser realParser = new ScParser(true, 5, 5, new AutoConfiguredLoadBalancerFactory("pick-first"));
resolver = new XdsNameResolver(null, AUTHORITY, realParser, syncContext, scheduler, xdsClientPoolFactory, mockRandom, FilterRegistry.getDefaultRegistry(), null);
resolver.start(mockListener);
FakeXdsClient xdsClient = (FakeXdsClient) resolver.getXdsClient();
RetryPolicy retryPolicy = RetryPolicy.create(4, ImmutableList.of(Code.UNAVAILABLE), Durations.fromMillis(100), Durations.fromMillis(200), null);
xdsClient.deliverLdsUpdate(Collections.singletonList(Route.forAction(RouteMatch.withPathExactOnly(call1.getFullMethodNameForPath()), RouteAction.forCluster(cluster1, Collections.<HashPolicy>emptyList(), null, retryPolicy), ImmutableMap.<String, FilterConfig>of())));
verify(mockListener).onResult(resolutionResultCaptor.capture());
ResolutionResult result = resolutionResultCaptor.getValue();
InternalConfigSelector configSelector = result.getAttributes().get(InternalConfigSelector.KEY);
Result selectResult = configSelector.selectConfig(new PickSubchannelArgsImpl(call1.methodDescriptor, new Metadata(), CallOptions.DEFAULT));
Object config = selectResult.getConfig();
// Purely validating the data (io.grpc.internal.RetryPolicy).
// However, there's no public accessor methods the data object.
assertThat(config.getClass().getName()).isEqualTo("io.grpc.internal.ManagedChannelServiceConfig");
assertThat(config.toString()).contains(MoreObjects.toStringHelper("RetryPolicy").add("maxAttempts", 4).add("initialBackoffNanos", TimeUnit.MILLISECONDS.toNanos(100)).add("maxBackoffNanos", TimeUnit.MILLISECONDS.toNanos(200)).add("backoffMultiplier", 2D).add("perAttemptRecvTimeoutNanos", null).add("retryableStatusCodes", ImmutableList.of(Code.UNAVAILABLE)).toString());
}
use of io.grpc.internal.PickSubchannelArgsImpl in project grpc-java by grpc.
the class RlsLoadBalancerTest method lb_nameResolutionFailed.
@Test
public void lb_nameResolutionFailed() throws Exception {
deliverResolvedAddresses();
InOrder inOrder = inOrder(helper);
inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.CONNECTING), pickerCaptor.capture());
SubchannelPicker picker = pickerCaptor.getValue();
Metadata headers = new Metadata();
PickResult res = picker.pickSubchannel(new PickSubchannelArgsImpl(fakeSearchMethod, headers, CallOptions.DEFAULT));
assertThat(res.getStatus().isOk()).isTrue();
assertThat(subchannelIsReady(res.getSubchannel())).isFalse();
inOrder.verify(helper).createSubchannel(any(CreateSubchannelArgs.class));
inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.CONNECTING), pickerCaptor.capture());
assertThat(subchannels).hasSize(1);
inOrder.verifyNoMoreInteractions();
FakeSubchannel searchSubchannel = subchannels.getLast();
searchSubchannel.updateState(ConnectivityStateInfo.forNonError(ConnectivityState.READY));
inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.READY), pickerCaptor.capture());
SubchannelPicker picker2 = pickerCaptor.getValue();
assertThat(picker2).isEqualTo(picker);
res = picker2.pickSubchannel(new PickSubchannelArgsImpl(fakeSearchMethod, headers, CallOptions.DEFAULT));
// verify success. Subchannel is wrapped, so checking attributes.
assertThat(subchannelIsReady(res.getSubchannel())).isTrue();
assertThat(res.getSubchannel().getAddresses()).isEqualTo(searchSubchannel.getAddresses());
assertThat(res.getSubchannel().getAttributes()).isEqualTo(searchSubchannel.getAttributes());
inOrder.verifyNoMoreInteractions();
rlsLb.handleNameResolutionError(Status.UNAVAILABLE);
verify(helper).updateBalancingState(eq(ConnectivityState.TRANSIENT_FAILURE), pickerCaptor.capture());
SubchannelPicker failedPicker = pickerCaptor.getValue();
res = failedPicker.pickSubchannel(new PickSubchannelArgsImpl(fakeSearchMethod, headers, CallOptions.DEFAULT));
assertThat(res.getStatus().isOk()).isFalse();
assertThat(subchannelIsReady(res.getSubchannel())).isFalse();
}
use of io.grpc.internal.PickSubchannelArgsImpl in project grpc-java by grpc.
the class RlsLoadBalancerTest method lb_working_withDefaultTarget.
@Test
public void lb_working_withDefaultTarget() throws Exception {
deliverResolvedAddresses();
InOrder inOrder = inOrder(helper);
inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.CONNECTING), pickerCaptor.capture());
SubchannelPicker picker = pickerCaptor.getValue();
Metadata headers = new Metadata();
PickResult res = picker.pickSubchannel(new PickSubchannelArgsImpl(fakeSearchMethod, headers, CallOptions.DEFAULT));
inOrder.verify(helper).createSubchannel(any(CreateSubchannelArgs.class));
inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.CONNECTING), any(SubchannelPicker.class));
inOrder.verifyNoMoreInteractions();
assertThat(res.getStatus().isOk()).isTrue();
assertThat(subchannelIsReady(res.getSubchannel())).isFalse();
assertThat(subchannels).hasSize(1);
FakeSubchannel searchSubchannel = subchannels.getLast();
searchSubchannel.updateState(ConnectivityStateInfo.forNonError(ConnectivityState.READY));
inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.READY), pickerCaptor.capture());
inOrder.verifyNoMoreInteractions();
assertThat(subchannelIsReady(res.getSubchannel())).isTrue();
assertThat(res.getSubchannel().getAddresses()).isEqualTo(searchSubchannel.getAddresses());
assertThat(res.getSubchannel().getAttributes()).isEqualTo(searchSubchannel.getAttributes());
// rescue should be pending status although the overall channel state is READY
res = picker.pickSubchannel(new PickSubchannelArgsImpl(fakeRescueMethod, headers, CallOptions.DEFAULT));
inOrder.verify(helper).createSubchannel(any(CreateSubchannelArgs.class));
// other rls picker itself is ready due to first channel.
inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.READY), pickerCaptor.capture());
inOrder.verifyNoMoreInteractions();
assertThat(res.getStatus().isOk()).isTrue();
assertThat(subchannelIsReady(res.getSubchannel())).isFalse();
assertThat(subchannels).hasSize(2);
FakeSubchannel rescueSubchannel = subchannels.getLast();
// search subchannel is down, rescue subchannel is connecting
searchSubchannel.updateState(ConnectivityStateInfo.forTransientFailure(Status.NOT_FOUND));
inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.CONNECTING), pickerCaptor.capture());
rescueSubchannel.updateState(ConnectivityStateInfo.forNonError(ConnectivityState.READY));
inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.READY), pickerCaptor.capture());
// search again, use pending fallback because searchSubchannel is in failure mode
res = picker.pickSubchannel(new PickSubchannelArgsImpl(fakeSearchMethod, headers, CallOptions.DEFAULT));
assertThat(res.getStatus().isOk()).isTrue();
assertThat(subchannelIsReady(res.getSubchannel())).isFalse();
inOrder.verify(helper).createSubchannel(any(CreateSubchannelArgs.class));
assertThat(subchannels).hasSize(3);
FakeSubchannel fallbackSubchannel = subchannels.getLast();
fallbackSubchannel.updateState(ConnectivityStateInfo.forNonError(ConnectivityState.READY));
inOrder.verify(helper, times(2)).updateBalancingState(eq(ConnectivityState.READY), pickerCaptor.capture());
inOrder.verifyNoMoreInteractions();
res = picker.pickSubchannel(new PickSubchannelArgsImpl(fakeSearchMethod, headers, CallOptions.DEFAULT));
assertThat(subchannelIsReady(res.getSubchannel())).isTrue();
assertThat(res.getSubchannel().getAddresses()).isEqualTo(searchSubchannel.getAddresses());
assertThat(res.getSubchannel().getAttributes()).isEqualTo(searchSubchannel.getAttributes());
res = picker.pickSubchannel(new PickSubchannelArgsImpl(fakeRescueMethod, headers, CallOptions.DEFAULT));
assertThat(subchannelIsReady(res.getSubchannel())).isTrue();
assertThat(res.getSubchannel().getAddresses()).isEqualTo(rescueSubchannel.getAddresses());
assertThat(res.getSubchannel().getAttributes()).isEqualTo(rescueSubchannel.getAttributes());
// all channels are failed
rescueSubchannel.updateState(ConnectivityStateInfo.forTransientFailure(Status.NOT_FOUND));
inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.READY), pickerCaptor.capture());
fallbackSubchannel.updateState(ConnectivityStateInfo.forTransientFailure(Status.NOT_FOUND));
inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.TRANSIENT_FAILURE), pickerCaptor.capture());
inOrder.verifyNoMoreInteractions();
}
use of io.grpc.internal.PickSubchannelArgsImpl in project grpc-java by grpc.
the class CachingRlsLbClientTest method get_updatesLbState.
@Test
public void get_updatesLbState() throws Exception {
setUpRlsLbClient();
InOrder inOrder = inOrder(helper);
RouteLookupRequest routeLookupRequest = RouteLookupRequest.create(ImmutableMap.of("server", "bigtable.googleapis.com", "service-key", "service1", "method-key", "create"));
rlsServerImpl.setLookupTable(ImmutableMap.of(routeLookupRequest, RouteLookupResponse.create(ImmutableList.of("primary.cloudbigtable.googleapis.com"), "header-rls-data-value")));
// valid channel
CachedRouteLookupResponse resp = getInSyncContext(routeLookupRequest);
assertThat(resp.isPending()).isTrue();
fakeTimeProvider.forwardTime(SERVER_LATENCY_MILLIS, TimeUnit.MILLISECONDS);
resp = getInSyncContext(routeLookupRequest);
assertThat(resp.hasData()).isTrue();
ArgumentCaptor<SubchannelPicker> pickerCaptor = ArgumentCaptor.forClass(SubchannelPicker.class);
ArgumentCaptor<ConnectivityState> stateCaptor = ArgumentCaptor.forClass(ConnectivityState.class);
inOrder.verify(helper, times(2)).updateBalancingState(stateCaptor.capture(), pickerCaptor.capture());
assertThat(new HashSet<>(pickerCaptor.getAllValues())).hasSize(1);
assertThat(stateCaptor.getAllValues()).containsExactly(ConnectivityState.CONNECTING, ConnectivityState.READY);
Metadata headers = new Metadata();
PickResult pickResult = pickerCaptor.getValue().pickSubchannel(new PickSubchannelArgsImpl(TestMethodDescriptors.voidMethod().toBuilder().setFullMethodName("service1/create").build(), headers, CallOptions.DEFAULT));
assertThat(pickResult.getStatus().isOk()).isTrue();
assertThat(pickResult.getSubchannel()).isNotNull();
assertThat(headers.get(RLS_DATA_KEY)).isEqualTo("header-rls-data-value");
// move backoff further back to only test error behavior
fakeBackoffProvider.nextPolicy = createBackoffPolicy(100, TimeUnit.MILLISECONDS);
// try to get invalid
RouteLookupRequest invalidRouteLookupRequest = RouteLookupRequest.create(ImmutableMap.<String, String>of());
CachedRouteLookupResponse errorResp = getInSyncContext(invalidRouteLookupRequest);
assertThat(errorResp.isPending()).isTrue();
fakeTimeProvider.forwardTime(SERVER_LATENCY_MILLIS, TimeUnit.MILLISECONDS);
errorResp = getInSyncContext(invalidRouteLookupRequest);
assertThat(errorResp.hasError()).isTrue();
// Channel is still READY because the subchannel for method /service1/create is still READY.
// Method /doesn/exists will use fallback child balancer and fail immediately.
inOrder.verify(helper).updateBalancingState(eq(ConnectivityState.READY), pickerCaptor.capture());
pickResult = pickerCaptor.getValue().pickSubchannel(new PickSubchannelArgsImpl(TestMethodDescriptors.voidMethod().toBuilder().setFullMethodName("doesn/exists").build(), headers, CallOptions.DEFAULT));
assertThat(pickResult.getStatus().getCode()).isEqualTo(Code.UNAVAILABLE);
assertThat(pickResult.getStatus().getDescription()).isEqualTo("fallback not available");
}
Aggregations