示例#1
0
        private void BuildReportFromMessage(INyxMessage message)
        {
            lock (NodesLock)
            {
                var added   = message.Get <IEnumerable <NodeInfo> >(NodeManagerAdded);
                var removed = message.Get <IEnumerable <NodeInfo> >(NodeManagerRemoved);
                var cleanup = message.Get <bool>(NodeManagerCleanup);
                // Cache all nodes info on borg.
                if (cleanup)
                {
                    _nodesInfo.Clear();
                    removed = new List <NodeInfo>(_nodesInfo);
                }
                else
                {
                    _nodesInfo.RemoveAll(p => removed.Any(r => p?.NodeId == r.NodeId));
                }

                var addedNodes = added as IList <NodeInfo> ?? added.ToList();
                if (added != null)
                {
                    _nodesInfo.RemoveAll(n => addedNodes.Any(o => o.NodeId == n.NodeId));
                    _nodesInfo.AddRange(addedNodes);
                }

                UpdateGroupInfo();
                // Internal broadcast the info to the message bus, so ui can get the updates.
                var managerMessage = new NodesChanges
                {
                    Added   = addedNodes,
                    Removed = removed,
                    All     = new List <NodeInfo>(_nodesInfo)
                };
                _nodesSubject.OnNext(managerMessage);
                _groupSubject.OnNext(_groups.Clone());
            }
        }
示例#2
0
        private void RunNodeCollector(INyxMessage message)
        {
            var info = message.Get <NodeInfo>(NodeManagerInfo);

            if (info == null)
            {
                return;
            }
            var sw = Stopwatch.StartNew();

            using (Disposable.Create(() =>
            {
                _logger.Trace("Hub node collector took {0}ms.", sw.ElapsedMilliseconds);
                sw.Stop();
            }))
            {
                if (message.Action == NodesPingStop)
                {
                    _logger.Debug("Received ping stop from {0}", StringExtensions.Trimmer(message.Source));
                    var indexToRemove = _nodesInfo.FindIndex(ni => ni.NodeId == message.Source);
                    if (indexToRemove == -1)
                    {
                        return;
                    }
                    var nodeToRemove = _nodesInfo.ElementAt(indexToRemove);
                    lock (NodesLock) _nodesInfo.RemoveAt(indexToRemove);
                    lock (UpdaterLock)
                    {
                        foreach (var update in _pushUpdates)
                        {
                            SendNodesInfo(null, update, new List <NodeInfo>(), new[] { nodeToRemove });
                        }
                    }
                    return;
                }

                bool dirty   = false;
                var  removed = new List <NodeInfo>();
                var  added   = new List <NodeInfo>();
                var  index   = _nodesInfo.FindIndex(ni => ni.NodeId == info.NodeId);
                if (index == -1)
                {
                    _nodesInfo.Add(info);
                    lock (NodesLock) added.Add(info);
                }
                else
                {
                    // Quick check for group changes
                    dirty = _nodesInfo[index].GetHashCode() != info.GetHashCode();
                    if (dirty)
                    {
                        lock (NodesLock) added.Add(info);
                    }
                    _nodesInfo[index] = info;
                }
                // Cleanup 140 seconds old nodes that don't respond.
                lock (NodesLock)
                {
                    _nodesInfo.RemoveAll(ni =>
                    {
                        var res = DateTime.Now.Subtract(ni.TimeStamp).TotalSeconds > 140;
                        if (res)
                        {
                            removed.Add(ni);
                        }
                        return(res);
                    });
                }
                // Remove dead subscriptions
                lock (UpdaterLock) _pushUpdates.RemoveWhere(p => _nodesInfo.All(ni => ni.NodeId != p));
                message.Remove(NodeManagerInfo);
                // Push updates only if something changed.
                if (added.Count == 0 && removed.Count == 0 && !dirty)
                {
                    return;
                }
                _logger.Debug("Added {0} nodes and removed {1}.", added.Count, removed.Count);
                lock (UpdaterLock)
                {
                    foreach (var update in _pushUpdates)
                    {
                        SendNodesInfo(null, update, added, removed);
                    }

                    // Notify any hub plugin listening to node changes
                    _nodesSubject.OnNext(new NodesChanges {
                        All = _nodesInfo.AsReadOnly(), Added = added.AsReadOnly(), Removed = removed.AsReadOnly()
                    });
                    _groupSubject.OnNext(_groups.Clone());
                }
            }
        }