public async Task <ServiceNodeInfo> GetNextNode(string serviceName, string serviceRoute, IReadOnlyList <object> serviceArgs, IReadOnlyDictionary <string, string> serviceMeta) { var nodes = await ServiceDiscovery.GetServiceNodes(serviceName); if (!nodes.Any()) { throw new NotFoundNodeException(serviceName); } if (nodes.Count == 1) { return(nodes.First()); } lock (LockObject) { _index++; if (_index > nodes.Count - 1) { _index = 0; } if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace($"Load to node {nodes[_index].ServiceId}."); } return(nodes[_index]); } }
public async Task <ServiceNodeInfo> GetNextNode(string serviceName, string serviceRoute, IReadOnlyList <object> serviceArgs, IReadOnlyDictionary <string, string> serviceMeta) { var nodes = await ServiceDiscovery.GetServiceNodes(serviceName); if (!nodes.Any()) { throw new NotFoundNodeException(serviceName); } if (nodes.Count == 1) { return(nodes.First()); } lock (LockObject) { var index = -1; var total = 0; for (var i = 0; i < nodes.Count; i++) { nodes[i].Attach.AddOrUpdate(Key, nodes[i].Weight, (key, old) => Convert.ToInt32(old) + nodes[i].Weight); total += nodes[i].Weight; if (index == -1 || GetCurrentWeightValue(nodes[index]) < GetCurrentWeightValue(nodes[i])) { index = i; } } nodes[index].Attach.AddOrUpdate(Key, -total, (k, old) => Convert.ToInt32(old) - total); var node = nodes[index]; if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace($"Load to node {node.ServiceId}."); } return(node); } }
public async Task <ServiceNodeInfo> GetNextNode(string serviceName, string serviceRoute, IReadOnlyList <object> serviceArgs, IReadOnlyDictionary <string, string> serviceMeta) { var nodes = await ServiceDiscovery.GetServiceNodes(serviceName); if (!nodes.Any()) { throw new NotFoundNodeException(serviceName); } if (nodes.Count == 1) { return(nodes.First()); } var node = nodes[new Random().Next(0, nodes.Count)]; if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace($"Load to node {node.ServiceId}."); } return(node); }
public async Task <ServiceNodeInfo> GetNextNode(string serviceName, string serviceRoute, IReadOnlyList <object> serviceArgs, IReadOnlyDictionary <string, string> serviceMeta) { var nodes = await ServiceDiscovery.GetServiceNodes(serviceName); if (!nodes.Any()) { throw new NotFoundNodeException(serviceName); } if (nodes.Count == 1) { return(nodes.First()); } lock (LockObject) { var total = nodes.Sum(p => p.Weight); var offset = new Random().Next(0, total + 1); var currentSum = 0; foreach (var node in nodes.OrderByDescending(p => p.Weight)) { currentSum += node.Weight; if (offset <= currentSum) { if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace($"Load to node {node.ServiceId}."); } return(node); } } var result = nodes[new Random().Next(0, nodes.Count)]; if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace($"Load to node {result.ServiceId}."); } return(result); } }
public async Task <ServiceNodeInfo> GetNextNode(string serviceName, string serviceRoute, IReadOnlyList <object> serviceArgs, IReadOnlyDictionary <string, string> serviceMeta) { var nodes = await ServiceDiscovery.GetServiceNodes(serviceName); if (!nodes.Any()) { throw new NotFoundNodeException(serviceName); } if (nodes.Count == 1) { return(nodes.First()); } lock (LockObject) { if (serviceMeta == null || !serviceMeta.TryGetValue("x-consistent-hash-key", out var key) || string.IsNullOrWhiteSpace(key)) { throw new ArgumentNullException(nameof(serviceMeta), "Service metadata [x-consistent-hash-key] is null,Please call SetMeta method to pass in."); } var selectedNode = ServicesInfo.GetOrAdd(serviceName, k => { var consistentHash = new ConsistentHash <ServiceNodeInfo>(); foreach (var node in nodes) { consistentHash.AddNode(node, node.ServiceId); } ServicesInfo.TryAdd(serviceName, consistentHash); return(consistentHash); }).GetNodeForKey(key); if (Logger.IsEnabled(LogLevel.Trace)) { Logger.LogTrace($"Load to node {selectedNode.ServiceId}."); } return(selectedNode); } }