/// <summary> /// 屏蔽 /// </summary> /// <param name="serviceName"></param> /// <param name="failedCallInvoker"></param> public void Revoke(string serviceName, ChannelWrapper channelWrapper) { lock (_lock) { if (channelWrapper == null) { return; } // channels if (_channelWrappers.TryGetValue(serviceName, out List <ChannelWrapper> channels) && channels.Any(oo => oo == channelWrapper)) { channels.Remove(channelWrapper); _channelWrappers.AddOrUpdate(serviceName, channels, (k, v) => channels); } // add black ServiceBlackPolicy.Add(serviceName, channelWrapper.Target); channelWrapper.ShutdownAsync(); // reinit callinvoker if (channels.Count <= 0) { GetSetChannels(serviceName, false); } } }
/// <summary> /// 初始化callinvoker /// </summary> /// <param name="serviceName"></param> /// <param name="filterBlack">过滤黑名单 default true</param> /// <returns></returns> private List <ChannelWrapper> GetSetChannels(string serviceName, bool filterBlack = true) { if (!_discoveries.TryGetValue(serviceName, out IEndpointDiscovery discovery)) { return(null); } _channelWrappers.TryGetValue(serviceName, out List <ChannelWrapper> channelWrappers); channelWrappers ??= new List <ChannelWrapper>(); var targets = discovery.FindServiceEndpoints(filterBlack); if ((targets?.Count ?? 0) <= 0) { // 如果consul 取不到 暂时直接使用本地缓存的连接(注册中心数据清空的情况--异常) _channelWrappers.TryGetValue(serviceName, out channelWrappers); return(channelWrappers); } foreach (var target in targets) { if (channelWrappers.Any(oo => oo.Target == target.target)) { continue; } var channel = GrpcChannel.ForAddress($"https://{target.target}", Constants.DefaultChannelOptions); var channelWrapper = new ChannelWrapper(target.serviceId, channel); channelWrappers.Add(channelWrapper); } // 移除已经销毁的callInvokers var destroyChannels = channelWrappers.Where(oo => !targets.Any(target => target.target == oo.Target)).ToList(); foreach (var channel in destroyChannels) { channelWrappers.Remove(channel); channel.ShutdownAsync(); } _channelWrappers.AddOrUpdate(serviceName, channelWrappers, (key, value) => channelWrappers); return(channelWrappers); }