use of io.grpc.LoadBalancer.PickSubchannelArgs in project grpc-java by grpc.
the class OobChannel method setSubchannel.
// Must be called only once, right after the OobChannel is created.
void setSubchannel(final InternalSubchannel subchannel) {
log.log(Level.FINE, "[{0}] Created with [{1}]", new Object[] { this, subchannel });
subchannelImpl = new SubchannelImpl() {
@Override
public void shutdown() {
subchannel.shutdown();
}
@Override
ClientTransport obtainActiveTransport() {
return subchannel.obtainActiveTransport();
}
@Override
public void requestConnection() {
subchannel.obtainActiveTransport();
}
@Override
public EquivalentAddressGroup getAddresses() {
return subchannel.getAddressGroup();
}
@Override
public Attributes getAttributes() {
return Attributes.EMPTY;
}
};
subchannelPicker = new SubchannelPicker() {
final PickResult result = PickResult.withSubchannel(subchannelImpl);
@Override
public PickResult pickSubchannel(PickSubchannelArgs args) {
return result;
}
};
delayedTransport.reprocess(subchannelPicker);
}
use of io.grpc.LoadBalancer.PickSubchannelArgs in project grpc-java by grpc.
the class GrpclbLoadBalancerTest method bufferPicker.
@Test
public void bufferPicker() {
PickSubchannelArgs args = mock(PickSubchannelArgs.class);
assertEquals(PickResult.withNoResult(), GrpclbLoadBalancer.BUFFER_PICKER.pickSubchannel(args));
verifyNoMoreInteractions(args);
}
use of io.grpc.LoadBalancer.PickSubchannelArgs in project grpc-java by grpc.
the class DelayedClientTransport method newStream.
/**
* If a {@link SubchannelPicker} is being, or has been provided via {@link #reprocess}, the last
* picker will be consulted.
*
* <p>Otherwise, if the delayed transport is not shutdown, then a {@link PendingStream} is
* returned; if the transport is shutdown, then a {@link FailingClientStream} is returned.
*/
@Override
public final ClientStream newStream(MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions, ClientStreamTracer[] tracers) {
try {
PickSubchannelArgs args = new PickSubchannelArgsImpl(method, headers, callOptions);
SubchannelPicker picker = null;
long pickerVersion = -1;
while (true) {
synchronized (lock) {
if (shutdownStatus != null) {
return new FailingClientStream(shutdownStatus, tracers);
}
if (lastPicker == null) {
return createPendingStream(args, tracers);
}
// Check for second time through the loop, and whether anything changed
if (picker != null && pickerVersion == lastPickerVersion) {
return createPendingStream(args, tracers);
}
picker = lastPicker;
pickerVersion = lastPickerVersion;
}
PickResult pickResult = picker.pickSubchannel(args);
ClientTransport transport = GrpcUtil.getTransportFromPickResult(pickResult, callOptions.isWaitForReady());
if (transport != null) {
return transport.newStream(args.getMethodDescriptor(), args.getHeaders(), args.getCallOptions(), tracers);
}
// This picker's conclusion is "buffer". If there hasn't been a newer picker set (possible
// race with reprocess()), we will buffer it. Otherwise, will try with the new picker.
}
} finally {
syncContext.drain();
}
}
use of io.grpc.LoadBalancer.PickSubchannelArgs 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.PickSubchannelArgs in project grpc-java by grpc.
the class RingHashLoadBalancerTest method skipFailingHosts_pickNextNonFailingHostInFirstTwoHosts.
@Test
public void skipFailingHosts_pickNextNonFailingHostInFirstTwoHosts() {
// 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 to force trying server2.
deliverSubchannelState(subchannels.get(Collections.singletonList(servers.get(0))), ConnectivityStateInfo.forTransientFailure(Status.UNAVAILABLE.withDescription("unreachable")));
verify(helper).updateBalancingState(eq(IDLE), pickerCaptor.capture());
PickResult result = pickerCaptor.getValue().pickSubchannel(args);
assertThat(result.getStatus().isOk()).isTrue();
// buffer request
assertThat(result.getSubchannel()).isNull();
verify(subchannels.get(Collections.singletonList(servers.get(2)))).requestConnection();
verify(subchannels.get(Collections.singletonList(servers.get(1))), never()).requestConnection();
deliverSubchannelState(subchannels.get(Collections.singletonList(servers.get(2))), ConnectivityStateInfo.forNonError(CONNECTING));
verify(helper).updateBalancingState(eq(CONNECTING), pickerCaptor.capture());
result = pickerCaptor.getValue().pickSubchannel(args);
assertThat(result.getStatus().isOk()).isTrue();
// buffer request
assertThat(result.getSubchannel()).isNull();
deliverSubchannelState(subchannels.get(Collections.singletonList(servers.get(2))), ConnectivityStateInfo.forNonError(READY));
verify(helper).updateBalancingState(eq(READY), pickerCaptor.capture());
result = pickerCaptor.getValue().pickSubchannel(args);
assertThat(result.getStatus().isOk()).isTrue();
assertThat(result.getSubchannel().getAddresses()).isEqualTo(servers.get(2));
}
Aggregations