public override void UpdateChannelState(ChannelState state) { _controller.UpdateState(new BalancerState(ConnectivityState.TransientFailure, new DropSubchannelPicker(this))); }
/// <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);