Пример #1
0
        private void UpdateSubchannelState(Subchannel subchannel, SubchannelState state)
        {
            var index = FindSubchannel(_addressSubchannels, subchannel);

            if (index == null)
            {
                SubchannelsLoadBalancerLog.IgnoredSubchannelStateChange(_logger, subchannel.Id);
                return;
            }

            SubchannelsLoadBalancerLog.ProcessingSubchannelStateChanged(_logger, subchannel.Id, state.State, state.Status);

            UpdateBalancingState(state.Status);

            if (state.State == ConnectivityState.TransientFailure || state.State == ConnectivityState.Idle)
            {
                SubchannelsLoadBalancerLog.RefreshingResolverForSubchannel(_logger, subchannel.Id, state.State);
                Controller.RefreshResolver();
            }
            if (state.State == ConnectivityState.Idle)
            {
                SubchannelsLoadBalancerLog.RequestingConnectionForSubchannel(_logger, subchannel.Id, state.State);
                subchannel.RequestConnection();
            }
        }
Пример #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);
        }