public override void UpdateChannelState(ChannelState state)
 {
     _controller.UpdateState(new BalancerState(ConnectivityState.TransientFailure, new DropSubchannelPicker(this)));
 }
Example #2
0
        /// <inheritdoc />
        public override void UpdateChannelState(ChannelState state)
        {
            if (state.Status.StatusCode != StatusCode.OK)
            {
                ResolverError(state.Status);
                return;
            }
            if (state.Addresses == null || state.Addresses.Count == 0)
            {
                ResolverError(new Status(StatusCode.Unavailable, "Resolver returned no addresses."));
                return;
            }

            var allUpdatedSubchannels = new List <AddressSubchannel>();
            var newSubchannels        = new List <Subchannel>();
            var currentSubchannels    = _addressSubchannels.ToList();

            // The state's addresses is the new authoritative list of addresses.
            // However, we want to keep existing subchannels when possible.
            foreach (var address in state.Addresses)
            {
                // Check existing subchannels for a match.
                var i = FindSubchannelByAddress(currentSubchannels, address);

                AddressSubchannel newOrCurrentSubConnection;
                if (i != null)
                {
                    // There is a match so take current subchannel.
                    newOrCurrentSubConnection = currentSubchannels[i.GetValueOrDefault()];

                    // Remove from current collection because any subchannels
                    // remaining in this collection at the end will be disposed.
                    currentSubchannels.RemoveAt(i.GetValueOrDefault());
                }
                else
                {
                    // No match so create a new subchannel.
                    var c = Controller.CreateSubchannel(new SubchannelOptions(new[] { address }));
                    c.OnStateChanged(s => UpdateSubchannelState(c, s));

                    newSubchannels.Add(c);
                    newOrCurrentSubConnection = new AddressSubchannel(c, address);
                }

                allUpdatedSubchannels.Add(newOrCurrentSubConnection);
            }

            // Any sub-connections still in this collection are no longer returned by the resolver.
            // This can all be removed.
            var removedSubConnections = currentSubchannels;

            if (removedSubConnections.Count == 0 && newSubchannels.Count == 0)
            {
                SubchannelsLoadBalancerLog.ConnectionsUnchanged(_logger);
                return;
            }

            foreach (var removedSubConnection in removedSubConnections)
            {
                RemoveSubchannel(removedSubConnection.Subchannel);
            }

            _addressSubchannels.Clear();
            _addressSubchannels.AddRange(allUpdatedSubchannels);

            // Start new connections after collection on balancer has been updated.
            foreach (var c in newSubchannels)
            {
                c.RequestConnection();
            }

            UpdateBalancingState(state.Status);
        }
 /// <summary>
 /// Updates the <see cref="LoadBalancer"/> with state from the <see cref="Resolver"/>.
 /// </summary>
 /// <param name="state">State from the <see cref="Resolver"/>.</param>
 public abstract void UpdateChannelState(ChannelState state);