private void RefreshNodes(string serviceName, List <ServiceNodeInfo> currentNodes) { if (ServiceNodes.TryGetValue(serviceName, out var nodes)) { if (!currentNodes.Any()) { nodes.Clear(); } var leavedNodes = nodes.Where(p => currentNodes.All(c => c.ServiceId != p.ServiceId)).Select(p => p.ServiceId).ToList(); if (leavedNodes.Any()) { Logger.LogTrace($"These nodes are gone:{string.Join(",", leavedNodes)}"); OnNodeLeave?.Invoke(serviceName, leavedNodes); nodes.RemoveAll(p => currentNodes.All(c => c.ServiceId != p.ServiceId)); } var addedNodes = currentNodes.FindAll(p => nodes.All(c => c.ServiceId != p.ServiceId)); if (addedNodes.Any()) { nodes.AddRange(addedNodes); Logger.LogTrace( $"New nodes added:{string.Join(",", addedNodes.Select(p => p.ServiceId))}"); OnNodeJoin?.Invoke(serviceName, addedNodes); } } else { if (!currentNodes.Any()) { ServiceNodes.TryAdd(serviceName, currentNodes); } } }
public async Task NodeMonitor(CancellationToken cancellationToken) { Logger.LogTrace("Start refresh service status,waiting for locking..."); using (await AsyncLock.LockAsync(cancellationToken)) { if (cancellationToken.IsCancellationRequested) { return; } foreach (var service in ServiceNodes) { Logger.LogTrace($"Service {service.Key} refreshing..."); try { var healthNodes = await QueryServiceAsync(service.Key, cancellationToken); if (cancellationToken.IsCancellationRequested) { break; } var leavedNodes = service.Value.Where(p => healthNodes.All(a => a.ServiceId != p.ServiceId)) .Select(p => p.ServiceId).ToArray(); if (leavedNodes.Any()) { //RemoveNode(service.Key, leavedNodes); if (!ServiceNodes.TryGetValue(service.Key, out var services)) { return; } services.RemoveAll(p => leavedNodes.Any(n => n == p.ServiceId)); OnNodeLeave?.Invoke(service.Key, leavedNodes); Logger.LogTrace($"These nodes are gone:{string.Join(",", leavedNodes)}"); } var addedNodes = healthNodes.Where(p => service.Value.All(e => e.ServiceId != p.ServiceId)).Select(p => new ServiceNodeInfo(p.ServiceId, p.Address, p.Port, p.Weight, p.EnableTls, p.Meta)) .ToList(); if (addedNodes.Any()) { //AddNode(service.Key, addedNodes); if (ServiceNodes.TryGetValue(service.Key, out var services)) { services.AddRange(addedNodes); } else { ServiceNodes.TryAdd(service.Key, addedNodes); } OnNodeJoin?.Invoke(service.Key, addedNodes); Logger.LogTrace( $"New nodes added:{string.Join(",", addedNodes.Select(p => p.ServiceId))}"); } } catch { // ignored } } Logger.LogTrace("Complete refresh."); } }