Search in sources :

Example 61 with EquivalentAddressGroup

use of io.grpc.EquivalentAddressGroup in project grpc-java by grpc.

the class GrpclbLoadBalancerTest method pickFirstMode_fallback.

@Test
public void pickFirstMode_fallback() throws Exception {
    InOrder inOrder = inOrder(helper);
    // Name resolver returns balancer and backend addresses
    List<EquivalentAddressGroup> backendList = createResolvedBackendAddresses(2);
    List<EquivalentAddressGroup> grpclbBalancerList = createResolvedBalancerAddresses(1);
    deliverResolvedAddresses(backendList, grpclbBalancerList, GrpclbConfig.create(Mode.PICK_FIRST));
    // Attempted to connect to balancer
    assertEquals(1, fakeOobChannels.size());
    verify(mockLbService).balanceLoad(lbResponseObserverCaptor.capture());
    StreamObserver<LoadBalanceResponse> lbResponseObserver = lbResponseObserverCaptor.getValue();
    assertEquals(1, lbRequestObservers.size());
    // Fallback timer expires with no response
    fakeClock.forwardTime(GrpclbState.FALLBACK_TIMEOUT_MS, TimeUnit.MILLISECONDS);
    // Entering fallback mode
    inOrder.verify(helper).createSubchannel(createSubchannelArgsCaptor.capture());
    CreateSubchannelArgs createSubchannelArgs = createSubchannelArgsCaptor.getValue();
    assertThat(createSubchannelArgs.getAddresses()).containsExactly(backendList.get(0), backendList.get(1));
    assertThat(mockSubchannels).hasSize(1);
    Subchannel subchannel = mockSubchannels.poll();
    // Initially IDLE
    inOrder.verify(helper).updateBalancingState(eq(IDLE), pickerCaptor.capture());
    RoundRobinPicker picker0 = (RoundRobinPicker) pickerCaptor.getValue();
    // READY
    deliverSubchannelState(subchannel, ConnectivityStateInfo.forNonError(READY));
    inOrder.verify(helper).updateBalancingState(eq(READY), pickerCaptor.capture());
    RoundRobinPicker picker1 = (RoundRobinPicker) pickerCaptor.getValue();
    assertThat(picker1.dropList).containsExactly(null, null);
    assertThat(picker1.pickList).containsExactly(new BackendEntry(subchannel, new TokenAttachingTracerFactory(null)));
    assertThat(picker0.dropList).containsExactly(null, null);
    assertThat(picker0.pickList).containsExactly(new IdleSubchannelEntry(subchannel, syncContext));
    // Finally, an LB response, which brings us out of fallback
    List<ServerEntry> backends1 = Arrays.asList(new ServerEntry("127.0.0.1", 2000, "token0001"), new ServerEntry("127.0.0.1", 2010, "token0002"));
    inOrder.verify(helper, never()).updateBalancingState(any(ConnectivityState.class), any(SubchannelPicker.class));
    lbResponseObserver.onNext(buildInitialResponse());
    lbResponseObserver.onNext(buildLbResponse(backends1));
    // new addresses will be updated to the existing subchannel
    // createSubchannel() has ever been called only once
    inOrder.verify(helper, never()).createSubchannel(any(CreateSubchannelArgs.class));
    assertThat(mockSubchannels).isEmpty();
    verify(subchannel).updateAddresses(eq(Arrays.asList(new EquivalentAddressGroup(backends1.get(0).addr, eagAttrsWithToken("token0001")), new EquivalentAddressGroup(backends1.get(1).addr, eagAttrsWithToken("token0002")))));
    inOrder.verify(helper).updateBalancingState(eq(READY), pickerCaptor.capture());
    RoundRobinPicker picker2 = (RoundRobinPicker) pickerCaptor.getValue();
    assertThat(picker2.dropList).containsExactly(null, null);
    assertThat(picker2.pickList).containsExactly(new BackendEntry(subchannel, new TokenAttachingTracerFactory(getLoadRecorder())));
    // PICK_FIRST doesn't use subchannelPool
    verify(subchannelPool, never()).takeOrCreateSubchannel(any(EquivalentAddressGroup.class), any(Attributes.class));
    verify(subchannelPool, never()).returnSubchannel(any(Subchannel.class), any(ConnectivityStateInfo.class));
}
Also used : BackendEntry(io.grpc.grpclb.GrpclbState.BackendEntry) InOrder(org.mockito.InOrder) Attributes(io.grpc.Attributes) InitialLoadBalanceResponse(io.grpc.lb.v1.InitialLoadBalanceResponse) LoadBalanceResponse(io.grpc.lb.v1.LoadBalanceResponse) IdleSubchannelEntry(io.grpc.grpclb.GrpclbState.IdleSubchannelEntry) SubchannelPicker(io.grpc.LoadBalancer.SubchannelPicker) RoundRobinPicker(io.grpc.grpclb.GrpclbState.RoundRobinPicker) ConnectivityState(io.grpc.ConnectivityState) ConnectivityStateInfo(io.grpc.ConnectivityStateInfo) CreateSubchannelArgs(io.grpc.LoadBalancer.CreateSubchannelArgs) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) Subchannel(io.grpc.LoadBalancer.Subchannel) Test(org.junit.Test)

Example 62 with EquivalentAddressGroup

use of io.grpc.EquivalentAddressGroup in project grpc-java by grpc.

the class GrpclbLoadBalancerTest method useIndependentRpcContext.

@Test
public void useIndependentRpcContext() {
    // Simulates making RPCs within the context of an inbound RPC.
    CancellableContext cancellableContext = Context.current().withCancellation();
    Context prevContext = cancellableContext.attach();
    try {
        List<EquivalentAddressGroup> backendList = createResolvedBackendAddresses(2);
        List<EquivalentAddressGroup> grpclbBalancerList = createResolvedBalancerAddresses(2);
        deliverResolvedAddresses(backendList, grpclbBalancerList);
        verify(helper).createOobChannel(eq(xattr(grpclbBalancerList)), eq(lbAuthority(0) + NO_USE_AUTHORITY_SUFFIX));
        verify(mockLbService).balanceLoad(lbResponseObserverCaptor.capture());
        StreamObserver<LoadBalanceResponse> lbResponseObserver = lbResponseObserverCaptor.getValue();
        assertEquals(1, lbRequestObservers.size());
        StreamObserver<LoadBalanceRequest> lbRequestObserver = lbRequestObservers.poll();
        verify(lbRequestObserver).onNext(eq(LoadBalanceRequest.newBuilder().setInitialRequest(InitialLoadBalanceRequest.newBuilder().setName(SERVICE_AUTHORITY).build()).build()));
        lbResponseObserver.onNext(buildInitialResponse());
        // The inbound RPC finishes and closes its context. The outbound RPC's control plane RPC
        // should not be impacted (no retry).
        cancellableContext.close();
        assertEquals(0, fakeClock.numPendingTasks(LB_RPC_RETRY_TASK_FILTER));
        verifyNoMoreInteractions(mockLbService);
    } finally {
        cancellableContext.detach(prevContext);
    }
}
Also used : SynchronizationContext(io.grpc.SynchronizationContext) Context(io.grpc.Context) CancellableContext(io.grpc.Context.CancellableContext) CancellableContext(io.grpc.Context.CancellableContext) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) LoadBalanceRequest(io.grpc.lb.v1.LoadBalanceRequest) InitialLoadBalanceRequest(io.grpc.lb.v1.InitialLoadBalanceRequest) InitialLoadBalanceResponse(io.grpc.lb.v1.InitialLoadBalanceResponse) LoadBalanceResponse(io.grpc.lb.v1.LoadBalanceResponse) Test(org.junit.Test)

Example 63 with EquivalentAddressGroup

use of io.grpc.EquivalentAddressGroup in project grpc-java by grpc.

the class GrpclbLoadBalancerTest method loadReporting.

@Test
public void loadReporting() {
    Metadata headers = new Metadata();
    PickSubchannelArgs args = mock(PickSubchannelArgs.class);
    when(args.getHeaders()).thenReturn(headers);
    long loadReportIntervalMillis = 1983;
    List<EquivalentAddressGroup> grpclbBalancerList = createResolvedBalancerAddresses(1);
    deliverResolvedAddresses(Collections.<EquivalentAddressGroup>emptyList(), grpclbBalancerList);
    // Fallback timer is started as soon as address is resolved.
    assertEquals(1, fakeClock.numPendingTasks(FALLBACK_MODE_TASK_FILTER));
    assertEquals(1, fakeOobChannels.size());
    verify(mockLbService).balanceLoad(lbResponseObserverCaptor.capture());
    StreamObserver<LoadBalanceResponse> lbResponseObserver = lbResponseObserverCaptor.getValue();
    assertEquals(1, lbRequestObservers.size());
    StreamObserver<LoadBalanceRequest> lbRequestObserver = lbRequestObservers.poll();
    InOrder inOrder = inOrder(lbRequestObserver);
    InOrder helperInOrder = inOrder(helper, subchannelPool);
    inOrder.verify(lbRequestObserver).onNext(eq(LoadBalanceRequest.newBuilder().setInitialRequest(InitialLoadBalanceRequest.newBuilder().setName(SERVICE_AUTHORITY).build()).build()));
    // Simulate receiving LB response
    assertEquals(0, fakeClock.numPendingTasks(LOAD_REPORTING_TASK_FILTER));
    lbResponseObserver.onNext(buildInitialResponse(loadReportIntervalMillis));
    // Load reporting task is scheduled
    assertEquals(1, fakeClock.numPendingTasks(LOAD_REPORTING_TASK_FILTER));
    assertEquals(0, fakeClock.runDueTasks());
    List<ServerEntry> backends = Arrays.asList(new ServerEntry("127.0.0.1", 2000, "token0001"), // drop
    new ServerEntry("token0001"), new ServerEntry("127.0.0.1", 2010, "token0002"), // drop
    new ServerEntry("token0003"));
    lbResponseObserver.onNext(buildLbResponse(backends));
    assertEquals(2, mockSubchannels.size());
    Subchannel subchannel1 = mockSubchannels.poll();
    Subchannel subchannel2 = mockSubchannels.poll();
    deliverSubchannelState(subchannel1, ConnectivityStateInfo.forNonError(CONNECTING));
    deliverSubchannelState(subchannel2, ConnectivityStateInfo.forNonError(CONNECTING));
    deliverSubchannelState(subchannel1, ConnectivityStateInfo.forNonError(READY));
    deliverSubchannelState(subchannel2, ConnectivityStateInfo.forNonError(READY));
    helperInOrder.verify(helper, atLeast(1)).updateBalancingState(eq(READY), pickerCaptor.capture());
    RoundRobinPicker picker = (RoundRobinPicker) pickerCaptor.getValue();
    assertThat(picker.dropList).containsExactly(null, new DropEntry(getLoadRecorder(), "token0001"), null, new DropEntry(getLoadRecorder(), "token0003")).inOrder();
    assertThat(picker.pickList).containsExactly(new BackendEntry(subchannel1, getLoadRecorder(), "token0001"), new BackendEntry(subchannel2, getLoadRecorder(), "token0002")).inOrder();
    // Report, no data
    assertNextReport(inOrder, lbRequestObserver, loadReportIntervalMillis, ClientStats.newBuilder().build());
    PickResult pick1 = picker.pickSubchannel(args);
    assertSame(subchannel1, pick1.getSubchannel());
    assertSame(getLoadRecorder(), pick1.getStreamTracerFactory());
    // Merely the pick will not be recorded as upstart.
    assertNextReport(inOrder, lbRequestObserver, loadReportIntervalMillis, ClientStats.newBuilder().build());
    ClientStreamTracer tracer1 = pick1.getStreamTracerFactory().newClientStreamTracer(STREAM_INFO, new Metadata());
    tracer1.streamCreated(Attributes.EMPTY, new Metadata());
    PickResult pick2 = picker.pickSubchannel(args);
    assertNull(pick2.getSubchannel());
    assertSame(DROP_PICK_RESULT, pick2);
    // Report includes upstart of pick1 and the drop of pick2
    assertNextReport(inOrder, lbRequestObserver, loadReportIntervalMillis, ClientStats.newBuilder().setNumCallsStarted(2).setNumCallsFinished(// pick2
    1).addCallsFinishedWithDrop(ClientStatsPerToken.newBuilder().setLoadBalanceToken("token0001").setNumCalls(// pick2
    1).build()).build());
    PickResult pick3 = picker.pickSubchannel(args);
    assertSame(subchannel2, pick3.getSubchannel());
    assertSame(getLoadRecorder(), pick3.getStreamTracerFactory());
    ClientStreamTracer tracer3 = pick3.getStreamTracerFactory().newClientStreamTracer(STREAM_INFO, new Metadata());
    tracer3.streamCreated(Attributes.EMPTY, new Metadata());
    // pick3 has sent out headers
    tracer3.outboundHeaders();
    // 3rd report includes pick3's upstart
    assertNextReport(inOrder, lbRequestObserver, loadReportIntervalMillis, ClientStats.newBuilder().setNumCallsStarted(1).build());
    PickResult pick4 = picker.pickSubchannel(args);
    assertNull(pick4.getSubchannel());
    assertSame(DROP_PICK_RESULT, pick4);
    // pick1 ended without sending anything
    tracer1.streamClosed(Status.CANCELLED);
    // 4th report includes end of pick1 and drop of pick4
    assertNextReport(inOrder, lbRequestObserver, loadReportIntervalMillis, ClientStats.newBuilder().setNumCallsStarted(// pick4
    1).setNumCallsFinished(2).setNumCallsFinishedWithClientFailedToSend(// pick1
    1).addCallsFinishedWithDrop(ClientStatsPerToken.newBuilder().setLoadBalanceToken("token0003").setNumCalls(// pick4
    1).build()).build());
    PickResult pick5 = picker.pickSubchannel(args);
    assertSame(subchannel1, pick1.getSubchannel());
    assertSame(getLoadRecorder(), pick5.getStreamTracerFactory());
    ClientStreamTracer tracer5 = pick5.getStreamTracerFactory().newClientStreamTracer(STREAM_INFO, new Metadata());
    tracer5.streamCreated(Attributes.EMPTY, new Metadata());
    // pick3 ended without receiving response headers
    tracer3.streamClosed(Status.DEADLINE_EXCEEDED);
    // pick5 sent and received headers
    tracer5.outboundHeaders();
    tracer5.inboundHeaders();
    // 5th report includes pick3's end and pick5's upstart
    assertNextReport(inOrder, lbRequestObserver, loadReportIntervalMillis, ClientStats.newBuilder().setNumCallsStarted(// pick5
    1).setNumCallsFinished(// pick3
    1).build());
    // pick5 ends
    tracer5.streamClosed(Status.OK);
    // 6th report includes pick5's end
    assertNextReport(inOrder, lbRequestObserver, loadReportIntervalMillis, ClientStats.newBuilder().setNumCallsFinished(1).setNumCallsFinishedKnownReceived(1).build());
    assertEquals(1, fakeClock.numPendingTasks());
    // Balancer closes the stream, scheduled reporting task cancelled
    lbResponseObserver.onError(Status.UNAVAILABLE.asException());
    assertEquals(0, fakeClock.numPendingTasks());
    // New stream created
    verify(mockLbService, times(2)).balanceLoad(lbResponseObserverCaptor.capture());
    lbResponseObserver = lbResponseObserverCaptor.getValue();
    assertEquals(1, lbRequestObservers.size());
    lbRequestObserver = lbRequestObservers.poll();
    inOrder = inOrder(lbRequestObserver);
    inOrder.verify(lbRequestObserver).onNext(eq(LoadBalanceRequest.newBuilder().setInitialRequest(InitialLoadBalanceRequest.newBuilder().setName(SERVICE_AUTHORITY).build()).build()));
    // Load reporting is also requested
    lbResponseObserver.onNext(buildInitialResponse(loadReportIntervalMillis));
    // No picker created because balancer is still using the results from the last stream
    helperInOrder.verify(helper, never()).updateBalancingState(any(ConnectivityState.class), any(SubchannelPicker.class));
    // Make a new pick on that picker.  It will not show up on the report of the new stream, because
    // that picker is associated with the previous stream.
    PickResult pick6 = picker.pickSubchannel(args);
    assertNull(pick6.getSubchannel());
    assertSame(DROP_PICK_RESULT, pick6);
    assertNextReport(inOrder, lbRequestObserver, loadReportIntervalMillis, ClientStats.newBuilder().build());
    // New stream got the list update
    lbResponseObserver.onNext(buildLbResponse(backends));
    // Same backends, thus no new subchannels
    helperInOrder.verify(subchannelPool, never()).takeOrCreateSubchannel(any(EquivalentAddressGroup.class), any(Attributes.class));
    // But the new RoundRobinEntries have a new loadRecorder, thus considered different from
    // the previous list, thus a new picker is created
    helperInOrder.verify(helper).updateBalancingState(eq(READY), pickerCaptor.capture());
    picker = (RoundRobinPicker) pickerCaptor.getValue();
    PickResult pick1p = picker.pickSubchannel(args);
    assertSame(subchannel1, pick1p.getSubchannel());
    assertSame(getLoadRecorder(), pick1p.getStreamTracerFactory());
    pick1p.getStreamTracerFactory().newClientStreamTracer(STREAM_INFO, new Metadata());
    // The pick from the new stream will be included in the report
    assertNextReport(inOrder, lbRequestObserver, loadReportIntervalMillis, ClientStats.newBuilder().setNumCallsStarted(1).build());
    verify(args, atLeast(0)).getHeaders();
    verifyNoMoreInteractions(args);
}
Also used : BackendEntry(io.grpc.grpclb.GrpclbState.BackendEntry) ClientStreamTracer(io.grpc.ClientStreamTracer) InOrder(org.mockito.InOrder) DropEntry(io.grpc.grpclb.GrpclbState.DropEntry) Metadata(io.grpc.Metadata) Attributes(io.grpc.Attributes) InitialLoadBalanceResponse(io.grpc.lb.v1.InitialLoadBalanceResponse) LoadBalanceResponse(io.grpc.lb.v1.LoadBalanceResponse) SubchannelPicker(io.grpc.LoadBalancer.SubchannelPicker) RoundRobinPicker(io.grpc.grpclb.GrpclbState.RoundRobinPicker) ConnectivityState(io.grpc.ConnectivityState) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) Subchannel(io.grpc.LoadBalancer.Subchannel) LoadBalanceRequest(io.grpc.lb.v1.LoadBalanceRequest) InitialLoadBalanceRequest(io.grpc.lb.v1.InitialLoadBalanceRequest) PickResult(io.grpc.LoadBalancer.PickResult) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) Test(org.junit.Test)

Example 64 with EquivalentAddressGroup

use of io.grpc.EquivalentAddressGroup in project grpc-java by grpc.

the class GrpclbNameResolverTest method resolve_presentResourceResolver.

@Test
public void resolve_presentResourceResolver() throws Exception {
    InetAddress backendAddr = InetAddress.getByAddress(new byte[] { 127, 0, 0, 0 });
    InetAddress lbAddr = InetAddress.getByAddress(new byte[] { 10, 1, 0, 0 });
    int lbPort = 8080;
    // original name in SRV record
    String lbName = "foo.example.com.";
    SrvRecord srvRecord = new SrvRecord(lbName, 8080);
    AddressResolver mockAddressResolver = mock(AddressResolver.class);
    when(mockAddressResolver.resolveAddress(hostName)).thenReturn(Collections.singletonList(backendAddr));
    when(mockAddressResolver.resolveAddress(lbName)).thenReturn(Collections.singletonList(lbAddr));
    ResourceResolver mockResourceResolver = mock(ResourceResolver.class);
    when(mockResourceResolver.resolveTxt(anyString())).thenReturn(Collections.singletonList("grpc_config=[{\"clientLanguage\": [\"java\"], \"serviceConfig\": {}}]"));
    when(mockResourceResolver.resolveSrv(anyString())).thenReturn(Collections.singletonList(srvRecord));
    when(serviceConfigParser.parseServiceConfig(ArgumentMatchers.<String, Object>anyMap())).thenAnswer(new Answer<ConfigOrError>() {

        @Override
        public ConfigOrError answer(InvocationOnMock invocation) {
            Object[] args = invocation.getArguments();
            return ConfigOrError.fromConfig(args[0]);
        }
    });
    resolver.setAddressResolver(mockAddressResolver);
    resolver.setResourceResolver(mockResourceResolver);
    resolver.start(mockListener);
    assertThat(fakeClock.runDueTasks()).isEqualTo(1);
    verify(mockListener).onResult(resultCaptor.capture());
    ResolutionResult result = resultCaptor.getValue();
    InetSocketAddress resolvedBackendAddr = (InetSocketAddress) Iterables.getOnlyElement(Iterables.getOnlyElement(result.getAddresses()).getAddresses());
    assertThat(resolvedBackendAddr.getAddress()).isEqualTo(backendAddr);
    EquivalentAddressGroup resolvedBalancerAddr = Iterables.getOnlyElement(result.getAttributes().get(GrpclbConstants.ATTR_LB_ADDRS));
    assertThat(resolvedBalancerAddr.getAttributes().get(GrpclbConstants.ATTR_LB_ADDR_AUTHORITY)).isEqualTo("foo.example.com");
    InetSocketAddress resolvedBalancerSockAddr = (InetSocketAddress) Iterables.getOnlyElement(resolvedBalancerAddr.getAddresses());
    assertThat(resolvedBalancerSockAddr.getAddress()).isEqualTo(lbAddr);
    assertThat(resolvedBalancerSockAddr.getPort()).isEqualTo(lbPort);
    assertThat(result.getServiceConfig().getConfig()).isNotNull();
    verify(mockAddressResolver).resolveAddress(hostName);
    verify(mockResourceResolver).resolveTxt("_grpc_config." + hostName);
    verify(mockResourceResolver).resolveSrv("_grpclb._tcp." + hostName);
}
Also used : AddressResolver(io.grpc.internal.DnsNameResolver.AddressResolver) InetSocketAddress(java.net.InetSocketAddress) ResolutionResult(io.grpc.NameResolver.ResolutionResult) SrvRecord(io.grpc.internal.DnsNameResolver.SrvRecord) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) InvocationOnMock(org.mockito.invocation.InvocationOnMock) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) ResourceResolver(io.grpc.internal.DnsNameResolver.ResourceResolver) ConfigOrError(io.grpc.NameResolver.ConfigOrError) InetAddress(java.net.InetAddress) Test(org.junit.Test)

Example 65 with EquivalentAddressGroup

use of io.grpc.EquivalentAddressGroup in project grpc-java by grpc.

the class GrpclbState method updateServerList.

/**
 * Populate backend servers to be used based on the given list of addresses.
 */
private void updateServerList(List<DropEntry> newDropList, List<BackendAddressGroup> newBackendAddrList, @Nullable GrpclbClientLoadRecorder loadRecorder) {
    HashMap<List<EquivalentAddressGroup>, Subchannel> newSubchannelMap = new HashMap<>();
    List<BackendEntry> newBackendList = new ArrayList<>();
    switch(config.getMode()) {
        case ROUND_ROBIN:
            for (BackendAddressGroup backendAddr : newBackendAddrList) {
                EquivalentAddressGroup eag = backendAddr.getAddresses();
                List<EquivalentAddressGroup> eagAsList = Collections.singletonList(eag);
                Subchannel subchannel = newSubchannelMap.get(eagAsList);
                if (subchannel == null) {
                    subchannel = subchannels.get(eagAsList);
                    if (subchannel == null) {
                        subchannel = subchannelPool.takeOrCreateSubchannel(eag, createSubchannelAttrs());
                        subchannel.requestConnection();
                    }
                    newSubchannelMap.put(eagAsList, subchannel);
                }
                BackendEntry entry;
                // Only picks with tokens are reported to LoadRecorder
                if (backendAddr.getToken() == null) {
                    entry = new BackendEntry(subchannel);
                } else {
                    entry = new BackendEntry(subchannel, loadRecorder, backendAddr.getToken());
                }
                newBackendList.add(entry);
            }
            // Close Subchannels whose addresses have been delisted
            for (Map.Entry<List<EquivalentAddressGroup>, Subchannel> entry : subchannels.entrySet()) {
                List<EquivalentAddressGroup> eagList = entry.getKey();
                if (!newSubchannelMap.containsKey(eagList)) {
                    returnSubchannelToPool(entry.getValue());
                }
            }
            subchannels = Collections.unmodifiableMap(newSubchannelMap);
            break;
        case PICK_FIRST:
            checkState(subchannels.size() <= 1, "Unexpected Subchannel count: %s", subchannels);
            final Subchannel subchannel;
            if (newBackendAddrList.isEmpty()) {
                if (subchannels.size() == 1) {
                    subchannel = subchannels.values().iterator().next();
                    subchannel.shutdown();
                    subchannels = Collections.emptyMap();
                }
                break;
            }
            List<EquivalentAddressGroup> eagList = new ArrayList<>();
            // The PICK_FIRST code path doesn't cache Subchannels.
            for (BackendAddressGroup bag : newBackendAddrList) {
                EquivalentAddressGroup origEag = bag.getAddresses();
                Attributes eagAttrs = origEag.getAttributes();
                if (bag.getToken() != null) {
                    eagAttrs = eagAttrs.toBuilder().set(GrpclbConstants.TOKEN_ATTRIBUTE_KEY, bag.getToken()).build();
                }
                eagList.add(new EquivalentAddressGroup(origEag.getAddresses(), eagAttrs));
            }
            if (subchannels.isEmpty()) {
                subchannel = helper.createSubchannel(CreateSubchannelArgs.newBuilder().setAddresses(eagList).setAttributes(createSubchannelAttrs()).build());
                subchannel.start(new SubchannelStateListener() {

                    @Override
                    public void onSubchannelState(ConnectivityStateInfo newState) {
                        handleSubchannelState(subchannel, newState);
                    }
                });
                if (requestConnectionPending) {
                    subchannel.requestConnection();
                    requestConnectionPending = false;
                }
            } else {
                subchannel = subchannels.values().iterator().next();
                subchannel.updateAddresses(eagList);
            }
            subchannels = Collections.singletonMap(eagList, subchannel);
            newBackendList.add(new BackendEntry(subchannel, new TokenAttachingTracerFactory(loadRecorder)));
            break;
        default:
            throw new AssertionError("Missing case for " + config.getMode());
    }
    dropList = Collections.unmodifiableList(newDropList);
    backendList = Collections.unmodifiableList(newBackendList);
}
Also used : SubchannelStateListener(io.grpc.LoadBalancer.SubchannelStateListener) PooledSubchannelStateListener(io.grpc.grpclb.SubchannelPool.PooledSubchannelStateListener) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Attributes(io.grpc.Attributes) ConnectivityStateInfo(io.grpc.ConnectivityStateInfo) Subchannel(io.grpc.LoadBalancer.Subchannel) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) ServerList(io.grpc.lb.v1.ServerList) List(java.util.List) ArrayList(java.util.ArrayList) Map(java.util.Map) HashMap(java.util.HashMap)

Aggregations

EquivalentAddressGroup (io.grpc.EquivalentAddressGroup)173 Test (org.junit.Test)133 Subchannel (io.grpc.LoadBalancer.Subchannel)54 SocketAddress (java.net.SocketAddress)42 SubchannelPicker (io.grpc.LoadBalancer.SubchannelPicker)41 PickSubchannelArgs (io.grpc.LoadBalancer.PickSubchannelArgs)39 Status (io.grpc.Status)39 Attributes (io.grpc.Attributes)37 CreateSubchannelArgs (io.grpc.LoadBalancer.CreateSubchannelArgs)33 InOrder (org.mockito.InOrder)31 Helper (io.grpc.LoadBalancer.Helper)30 Metadata (io.grpc.Metadata)29 ArrayList (java.util.ArrayList)26 InetSocketAddress (java.net.InetSocketAddress)24 PickResult (io.grpc.LoadBalancer.PickResult)22 UnsupportedClientTransportFactoryBuilder (io.grpc.internal.ManagedChannelImplBuilder.UnsupportedClientTransportFactoryBuilder)20 PolicySelection (io.grpc.internal.ServiceConfigUtil.PolicySelection)20 InitialLoadBalanceResponse (io.grpc.lb.v1.InitialLoadBalanceResponse)19 LoadBalanceResponse (io.grpc.lb.v1.LoadBalanceResponse)19 ClientTransportFactoryBuilder (io.grpc.internal.ManagedChannelImplBuilder.ClientTransportFactoryBuilder)18