Beispiel #1
0
 public RelayNodeClusterDefinition GetMyCluster()
 {
     if (!lookedForCluster)
     {
         lock (myClusterLock)
         {
             if (!lookedForCluster)
             {
                 RelayNodeGroupDefinition myGroup = GetMyGroup();
                 if (myGroup != null)
                 {
                     int portNumber;
                     List <IPAddress> addresses;
                     GetMyNetworkInfo(out addresses, out portNumber);
                     if (portNumber != 0 && addresses != null)
                     {
                         foreach (IPAddress address in addresses)
                         {
                             myCluster = myGroup.GetClusterFor(address, portNumber);
                             if (myCluster != null)
                             {
                                 break;
                             }
                         }
                     }
                 }
                 lookedForCluster = true;
             }
         }
     }
     return(myCluster);
 }
Beispiel #2
0
        internal NodeGroup(RelayNodeGroupDefinition groupDefinition, RelayNodeConfig nodeConfig, ForwardingConfig forwardingConfig)
        {
            GroupDefinition   = groupDefinition;
            Activated         = groupDefinition.Activated;
            _clusterByRange   = groupDefinition.UseIdRanges;
            _forwardingConfig = forwardingConfig;

            RelayNodeClusterDefinition myClusterDefinition = NodeManager.Instance.GetMyNodeClusterDefinition();

            foreach (RelayNodeClusterDefinition clusterDefintion in groupDefinition.RelayNodeClusters)
            {
                NodeCluster nodeCluster = new NodeCluster(clusterDefintion, nodeConfig, this, forwardingConfig);
                if (clusterDefintion == myClusterDefinition)
                {
                    MyCluster = nodeCluster;
                }
                Clusters.Add(nodeCluster);
            }

            _nodeReselectTimerCallback = new System.Threading.TimerCallback(NodeReselectTimer_Elapsed);
            if (_nodeReselectTimer == null)
            {
                _nodeReselectTimer = new System.Threading.Timer(_nodeReselectTimerCallback);
            }
            _nodeReselectTimer.Change(NodeReselectIntervalMilliseconds, NodeReselectIntervalMilliseconds);

            QueueTimerCallback = new System.Threading.TimerCallback(QueueTimer_Elapsed);
            if (QueueTimer == null)
            {
                QueueTimer = new System.Threading.Timer(QueueTimerCallback);
            }
            QueueTimer.Change(DequeueIntervalMilliseconds, DequeueIntervalMilliseconds);
        }
Beispiel #3
0
        internal void ReloadMapping(RelayNodeGroupDefinition groupDefinition, RelayNodeConfig newConfig, ForwardingConfig newForwardingConfig)
        {
            RelayNodeClusterDefinition myClusterDefinition = newConfig.GetMyCluster();

            Activated         = groupDefinition.Activated;
            GroupDefinition   = groupDefinition;
            _clusterByRange   = groupDefinition.UseIdRanges;
            _forwardingConfig = newForwardingConfig;

            if (groupDefinition.RelayNodeClusters.Length == Clusters.Count)
            {
                //same number of clusters, just let the clusters rebuild themselves. the clusters will entirely rebuild, so shuffinling around servers should be okay
                if (_log.IsDebugEnabled)
                {
                    _log.DebugFormat("Rebuilding existing clusters in group {0}.", groupDefinition.Name);
                }
                for (int i = 0; i < groupDefinition.RelayNodeClusters.Length; i++)
                {
                    Clusters[i].ReloadMapping(groupDefinition.RelayNodeClusters[i], newConfig, newForwardingConfig);
                    if (groupDefinition.RelayNodeClusters[i] == myClusterDefinition)
                    {
                        MyCluster = Clusters[i];
                    }
                }
                if (myClusterDefinition == null && MyCluster != null)
                {
                    if (_log.IsInfoEnabled)
                    {
                        _log.InfoFormat("Group {0} no longer contains this server. Removing.", GroupName);
                    }
                    //this group no longer contains "me". If it DID contain "me", it would've been set above.
                    MyCluster = null;
                }
            }
            else
            {
                //build new clusters and replace the existing ones with them
                if (_log.IsInfoEnabled)
                {
                    _log.InfoFormat("Number of clusters in group {0} changed, rebuilding.", groupDefinition.Name);
                }
                NodeCluster        myCluster   = null;
                List <NodeCluster> newClusters = new List <NodeCluster>();
                foreach (RelayNodeClusterDefinition clusterDefintion in groupDefinition.RelayNodeClusters)
                {
                    NodeCluster nodeCluster = new NodeCluster(clusterDefintion, newConfig, this, newForwardingConfig);
                    if (clusterDefintion == myClusterDefinition)
                    {
                        myCluster = nodeCluster;
                    }
                    newClusters.Add(nodeCluster);
                }
                Clusters  = newClusters;
                MyCluster = myCluster;
            }
            _nodeReselectTimer.Change(NodeReselectIntervalMilliseconds, NodeReselectIntervalMilliseconds);
        }
Beispiel #4
0
        internal NodeCluster(RelayNodeClusterDefinition clusterDefinition, RelayNodeConfig nodeConfig, NodeGroup nodeGroup, ForwardingConfig forwardingConfig)
        {
            _nodeGroup         = nodeGroup;
            _clusterDefinition = clusterDefinition;
            _minimumId         = clusterDefinition.MinId;
            _maximumId         = clusterDefinition.MaxId;

            RelayNodeDefinition meDefinition = nodeConfig.GetMyNode();

            _meInThisCluster = false;

            _localZone       = nodeConfig.GetLocalZone();
            _zoneDefinitions = nodeConfig.RelayNodeMapping.ZoneDefinitions;
            foreach (RelayNodeDefinition nodeDefinition in clusterDefinition.RelayNodes)
            {
                if (meDefinition == nodeDefinition)
                {
                    _meInThisCluster = true;
                }
            }

            DispatcherQueue nodeInQueue, nodeOutQueue;

            if (_meInThisCluster)
            {
                GetMessageQueuesFor(GetMessageQueueNameFor(meDefinition), clusterDefinition,
                                    NodeManager.Instance.InMessageDispatcher, NodeManager.Instance.OutMessageDispatcher,
                                    out nodeInQueue, out nodeOutQueue);

                Me = new Node(meDefinition, nodeGroup, this, forwardingConfig,
                              nodeInQueue, nodeOutQueue);
            }

            ushort maxDetectedZone = _localZone;

            foreach (RelayNodeDefinition nodeDefinition in clusterDefinition.RelayNodes)
            {
                if (nodeDefinition != meDefinition)
                {
                    GetMessageQueuesFor(GetMessageQueueNameFor(nodeDefinition), clusterDefinition,
                                        NodeManager.Instance.InMessageDispatcher, NodeManager.Instance.OutMessageDispatcher,
                                        out nodeInQueue, out nodeOutQueue);
                    Node node = new Node(nodeDefinition, nodeGroup, this, forwardingConfig,
                                         nodeInQueue, nodeOutQueue);

                    Nodes.Add(node);

                    if (node.Zone > maxDetectedZone)
                    {
                        maxDetectedZone = node.Zone;
                    }
                }
            }

            _nodesByZone = CalculateNodesByZone(Nodes, maxDetectedZone);
        }
		internal static string GetQueueNameFor(RelayNodeClusterDefinition definition)
		{
			StringBuilder sb = new StringBuilder();
			sb.Append("Relay Cluster ");
			for (int i = 0; i < definition.RelayNodes.Length; i++)
			{
				sb.Append(definition.RelayNodes[i].ToString());
				if (i < definition.RelayNodes.Length - 1)
				{
					sb.Append(", ");
				}
			}
			return sb.ToString();
		}
Beispiel #6
0
        internal static string GetQueueNameFor(RelayNodeClusterDefinition definition)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("Relay Cluster ");
            for (int i = 0; i < definition.RelayNodes.Length; i++)
            {
                sb.Append(definition.RelayNodes[i].ToString());
                if (i < definition.RelayNodes.Length - 1)
                {
                    sb.Append(", ");
                }
            }
            return(sb.ToString());
        }
Beispiel #7
0
        internal void GetMessageQueuesFor(RelayNodeDefinition node, RelayNodeClusterDefinition cluster,
                                          Dispatcher inDispatcher, Dispatcher outDispatcher,
                                          out DispatcherQueue inMessageQueue, out DispatcherQueue outMessageQueue)
        {
            string queueName;
            int    queueDepth;

            if (Me == null)             //not in this cluster, going to use the cluster wide message queues
            {
                queueName  = GetQueueNameFor(cluster);
                queueDepth = _nodeGroup.GetClusterQueueDepth();
            }
            else             //going to use the message queues that are per-node
            {
                queueName  = Node.GetMessageQueueNameFor(node);
                queueDepth = _nodeGroup.GetClusterQueueDepth() / cluster.RelayNodes.Length;
            }
            NodeManager.GetMessageQueues(inDispatcher, outDispatcher, queueName, queueDepth,
                                         out inMessageQueue, out outMessageQueue);
        }
        /// <summary>
        /// Initializes the cluster info.
        /// </summary>
        /// <param name="myClusterPos">My cluster pos.</param>
        /// <param name="numClustersInGroup">The num clusters in group.</param>
        /// <param name="myZone">My zone.</param>
        private static void InitializeClusterInfo(out int myClusterPos, out int numClustersInGroup, out ushort myZone)
        {
            RelayNodeGroupDefinition myGroup = RelayNodeConfig.GetRelayNodeConfig().GetMyGroup();

            RelayNodeClusterDefinition myCluster = RelayNodeConfig.GetRelayNodeConfig().GetMyCluster();

            RelayNodeDefinition myNode = RelayNodeConfig.GetRelayNodeConfig().GetMyNode();

            myZone             = myNode.Zone;
            numClustersInGroup = myGroup.RelayNodeClusters.Length;
            myClusterPos       = 0;

            foreach (RelayNodeClusterDefinition cluster in myGroup.RelayNodeClusters)
            {
                if (cluster.RelayNodes.Length == myCluster.RelayNodes.Length &&
                    cluster.ContainsNode(myNode.IPAddress, myNode.Port))
                {
                    // this cluster contains my Node
                    break;
                }
                myClusterPos++;
            }
        }
Beispiel #9
0
        internal NodeCluster(RelayNodeClusterDefinition clusterDefinition, RelayNodeConfig nodeConfig, NodeGroup nodeGroup, ForwardingConfig forwardingConfig)
        {
            _nodeGroup                 = nodeGroup;
            _clusterDefinition         = clusterDefinition;
            _minimumId                 = clusterDefinition.MinId;
            _maximumId                 = clusterDefinition.MaxId;
            NodeSelectionHopWindowSize = nodeGroup.NodeSelectionHopWindowSize;
            RelayNodeDefinition meDefinition = nodeConfig.GetMyNode();

            _meInThisCluster = false;
            _mapNetwork      = forwardingConfig.MapNetwork;
            _localZone       = nodeConfig.GetLocalZone();
            _zoneDefinitions = nodeConfig.RelayNodeMapping.ZoneDefinitions;
            foreach (RelayNodeDefinition nodeDefinition in clusterDefinition.RelayNodes)
            {
                if (meDefinition == nodeDefinition)
                {
                    _meInThisCluster = true;
                }
            }

            DispatcherQueue nodeInQueue, nodeOutQueue;

            if (_meInThisCluster)
            {
                GetMessageQueuesFor(meDefinition, clusterDefinition,
                                    NodeManager.Instance.InMessageDispatcher, NodeManager.Instance.OutMessageDispatcher,
                                    out nodeInQueue, out nodeOutQueue);

                Me = new Node(meDefinition, nodeGroup, this, forwardingConfig,
                              nodeInQueue, nodeOutQueue);
            }

            ushort maxDetectedZone = _localZone;

            foreach (RelayNodeDefinition nodeDefinition in clusterDefinition.RelayNodes)
            {
                if (nodeDefinition != meDefinition)
                {
                    GetMessageQueuesFor(nodeDefinition, clusterDefinition,
                                        NodeManager.Instance.InMessageDispatcher, NodeManager.Instance.OutMessageDispatcher,
                                        out nodeInQueue, out nodeOutQueue);
                    Node node = new Node(nodeDefinition, nodeGroup, this, forwardingConfig,
                                         nodeInQueue, nodeOutQueue);

                    Nodes.Add(node);

                    if (node.DetectedZone > maxDetectedZone)
                    {
                        maxDetectedZone = node.DetectedZone;
                    }
                    if (node.Zone > maxDetectedZone)
                    {
                        maxDetectedZone = node.Zone;
                    }

                    if (!ZoneNodes.ContainsKey(nodeDefinition.Zone))
                    {
                        ZoneNodes[nodeDefinition.Zone] = new List <Node>();
                    }

                    ZoneNodes[nodeDefinition.Zone].Add(node);
                }
            }

            _nodesByNumberOfHops = CalculateTopography(Nodes, MaximumHops);
            _nodeLayers          = CalculateNodeLayers(_nodesByNumberOfHops, NodeSelectionHopWindowSize);
            _nodesByDetectedZone = CalculateNodesByDetectedZone(Nodes, maxDetectedZone);
        }
Beispiel #10
0
        internal void ReloadMapping(RelayNodeClusterDefinition relayNodeClusterDefinition, RelayNodeConfig newConfig, ForwardingConfig forwardingConfig)
        {
            _minimumId  = relayNodeClusterDefinition.MinId;
            _maximumId  = relayNodeClusterDefinition.MaxId;
            _mapNetwork = forwardingConfig.MapNetwork;

            //figure out if anything changed. if it did, rebuild

            bool rebuild = false;

            ushort newLocalZone = newConfig.GetLocalZone();

            if (newLocalZone != _localZone)
            {
                rebuild    = true;
                _localZone = newLocalZone;
            }
            else
            {
                if ((_zoneDefinitions == null && newConfig.RelayNodeMapping.ZoneDefinitions != null) ||
                    (_zoneDefinitions != null && newConfig.RelayNodeMapping.ZoneDefinitions == null) ||
                    (_zoneDefinitions != null && !_zoneDefinitions.Equals(newConfig.RelayNodeMapping.ZoneDefinitions)))
                {
                    rebuild          = true;
                    _zoneDefinitions = newConfig.RelayNodeMapping.ZoneDefinitions;
                }
            }


            int effectiveSize = (!_meInThisCluster ? Nodes.Count : Nodes.Count + 1);

            //if there's a different number of nodes, we definitely have to rebuild
            if (relayNodeClusterDefinition.RelayNodes.Length != effectiveSize)
            {
                if (_log.IsInfoEnabled)
                {
                    _log.InfoFormat("Number of nodes in a cluster in group {0} changed from {1} to {2}, rebuilding", _nodeGroup.GroupName, effectiveSize, relayNodeClusterDefinition.RelayNodes.Length);
                }
                rebuild = true;
            }
            else
            {
                //if any of the nodes we do have aren't in the config, rebuild
                foreach (Node node in Nodes)
                {
                    if (!relayNodeClusterDefinition.ContainsNode(node.EndPoint.Address, node.EndPoint.Port))
                    {
                        if (_log.IsInfoEnabled)
                        {
                            _log.InfoFormat("Node {0} is no longer found in its cluster in group {1}, rebuilding.",
                                            node, _nodeGroup.GroupName);
                        }
                        rebuild = true;
                        break;
                    }
                }
                if (!rebuild && _nodeGroup.NodeSelectionHopWindowSize != NodeSelectionHopWindowSize)
                {
                    NodeSelectionHopWindowSize = _nodeGroup.NodeSelectionHopWindowSize;
                    rebuild = true;
                }

                if (!rebuild && _meInThisCluster)
                {
                    if (!relayNodeClusterDefinition.ContainsNode(Me.EndPoint.Address, Me.EndPoint.Port))
                    {
                        if (_log.IsInfoEnabled)
                        {
                            _log.InfoFormat("Node {0} (this machine) is no longer found in its cluster in group {1}, rebuilding.",
                                            Me, _nodeGroup.GroupName);
                        }
                        rebuild = true;
                    }
                }

                //or if there are any nodes in the config that aren't here, rebuild
                if (!rebuild)
                {
                    foreach (RelayNodeDefinition nodeDefinition in relayNodeClusterDefinition.RelayNodes)
                    {
                        if (!ContainsNode(nodeDefinition))
                        {
                            if (_log.IsInfoEnabled)
                            {
                                _log.InfoFormat("Node {0} is defined in the new config but does not exist in this cluster in group {1}, rebuilding.",
                                                nodeDefinition, _nodeGroup.GroupName);
                            }
                            rebuild = true;
                            break;
                        }
                    }
                }
            }

            if (rebuild)
            {
                Dictionary <ushort, List <Node> > newZoneNodes = new Dictionary <ushort, List <Node> >();
                List <Node> newNodes = new List <Node>();

                RelayNodeDefinition meDefinition = newConfig.GetMyNode();
                DispatcherQueue     nodeInQueue, nodeOutQueue;

                if (meDefinition != null)
                {
                    GetMessageQueuesFor(meDefinition, relayNodeClusterDefinition,
                                        NodeManager.Instance.InMessageDispatcher, NodeManager.Instance.OutMessageDispatcher,
                                        out nodeInQueue, out nodeOutQueue);
                    //Me is in the new config
                    //Either create it new or overwrite the old one
                    Me = new Node(meDefinition, _nodeGroup, this, forwardingConfig,
                                  nodeInQueue, nodeOutQueue);
                }
                else
                {
                    //me is NOT in the new config.
                    Me = null;
                }
                ushort maxDetectedZone = _localZone;
                foreach (RelayNodeDefinition nodeDefinition in relayNodeClusterDefinition.RelayNodes)
                {
                    if (nodeDefinition != meDefinition)
                    {
                        GetMessageQueuesFor(nodeDefinition, relayNodeClusterDefinition,
                                            NodeManager.Instance.InMessageDispatcher, NodeManager.Instance.OutMessageDispatcher,
                                            out nodeInQueue, out nodeOutQueue);

                        Node node = new Node(nodeDefinition, _nodeGroup, this, forwardingConfig,
                                             nodeInQueue, nodeOutQueue);

                        newNodes.Add(node);
                        if (node.DetectedZone > maxDetectedZone)
                        {
                            maxDetectedZone = node.DetectedZone;
                        }
                        if (node.Zone > maxDetectedZone)
                        {
                            maxDetectedZone = node.Zone;
                        }
                        if (!newZoneNodes.ContainsKey(nodeDefinition.Zone))
                        {
                            newZoneNodes[nodeDefinition.Zone] = new List <Node>();
                        }

                        newZoneNodes[nodeDefinition.Zone].Add(node);
                    }
                }
                Nodes                = newNodes;
                ZoneNodes            = newZoneNodes;
                _nodesByNumberOfHops = CalculateTopography(Nodes, MaximumHops);
                _nodeLayers          = CalculateNodeLayers(_nodesByNumberOfHops, NodeSelectionHopWindowSize);
                _nodesByDetectedZone = CalculateNodesByDetectedZone(Nodes, maxDetectedZone);
                lock (_chooseLock)
                {
                    ChosenNode = null;
                }
                ChosenZoneNodes = new Dictionary <ushort, Node>();
            }
            else
            {
                //just reload the configs to get any new network or queue settings
                bool   hitMe    = false;
                string meString = String.Empty;
                if (Me != null)
                {
                    meString = Me.ToString();
                }
                for (int i = 0; i < relayNodeClusterDefinition.RelayNodes.Length; i++)
                {
                    string definitionString = relayNodeClusterDefinition.RelayNodes[i].Host + ":" + relayNodeClusterDefinition.RelayNodes[i].Port;
                    if (definitionString == meString)
                    {
                        hitMe = true;
                        Me.ReloadMapping(relayNodeClusterDefinition.RelayNodes[i], forwardingConfig);
                    }
                    else
                    {
                        Nodes[(hitMe ? i - 1 : i)].ReloadMapping(relayNodeClusterDefinition.RelayNodes[i], forwardingConfig);
                    }
                }
                lock (_chooseLock)
                {
                    ChosenNode = null;
                }
            }
        }
		internal void GetMessageQueuesFor(RelayNodeDefinition node, RelayNodeClusterDefinition cluster,
			Dispatcher inDispatcher, Dispatcher outDispatcher,
			out DispatcherQueue inMessageQueue, out DispatcherQueue outMessageQueue)
		{
			string queueName;
			int queueDepth;
			if (Me == null) //not in this cluster, going to use the cluster wide message queues
			{
				queueName = GetQueueNameFor(cluster);
				queueDepth = _nodeGroup.GetClusterQueueDepth();                                
			}
			else //going to use the message queues that are per-node
			{   
				queueName = Node.GetMessageQueueNameFor(node);
				queueDepth = _nodeGroup.GetClusterQueueDepth() / cluster.RelayNodes.Length;
				
			}
			NodeManager.GetMessageQueues(inDispatcher, outDispatcher, queueName, queueDepth,
					out inMessageQueue, out outMessageQueue);
		}
		internal NodeCluster(RelayNodeClusterDefinition clusterDefinition, RelayNodeConfig nodeConfig, NodeGroup nodeGroup, ForwardingConfig forwardingConfig)
		{
			_nodeGroup = nodeGroup;
			_clusterDefinition = clusterDefinition;
			_minimumId = clusterDefinition.MinId;
			_maximumId = clusterDefinition.MaxId;
			NodeSelectionHopWindowSize = nodeGroup.NodeSelectionHopWindowSize;
			RelayNodeDefinition meDefinition = nodeConfig.GetMyNode();
			_meInThisCluster = false;
			_mapNetwork = forwardingConfig.MapNetwork;
			_localZone = nodeConfig.GetLocalZone();
			_zoneDefinitions = nodeConfig.RelayNodeMapping.ZoneDefinitions;
			foreach (RelayNodeDefinition nodeDefinition in clusterDefinition.RelayNodes)
			{
				if (meDefinition == nodeDefinition)
				{
					_meInThisCluster = true;
				}
			}
			
			DispatcherQueue nodeInQueue, nodeOutQueue;

			if (_meInThisCluster)
			{
				GetMessageQueuesFor(meDefinition, clusterDefinition,
					NodeManager.Instance.InMessageDispatcher, NodeManager.Instance.OutMessageDispatcher,
					out nodeInQueue, out nodeOutQueue);

				Me = new Node(meDefinition, nodeGroup, this, forwardingConfig,
						nodeInQueue, nodeOutQueue);
			}			

			ushort maxDetectedZone = _localZone;
			foreach (RelayNodeDefinition nodeDefinition in clusterDefinition.RelayNodes)
			{
				if (nodeDefinition != meDefinition)
				{
					GetMessageQueuesFor(nodeDefinition, clusterDefinition,
						NodeManager.Instance.InMessageDispatcher, NodeManager.Instance.OutMessageDispatcher,
						out nodeInQueue, out nodeOutQueue);
					Node node = new Node(nodeDefinition, nodeGroup, this, forwardingConfig,
						nodeInQueue, nodeOutQueue);

					Nodes.Add(node);

					if (node.DetectedZone > maxDetectedZone)
					{
						maxDetectedZone = node.DetectedZone;
					}
					if (node.Zone > maxDetectedZone)
					{
						maxDetectedZone = node.Zone;
					}

					if (!ZoneNodes.ContainsKey(nodeDefinition.Zone))
					{
						ZoneNodes[nodeDefinition.Zone] = new List<Node>();
					}

					ZoneNodes[nodeDefinition.Zone].Add(node);
				}				
			}

			_nodesByNumberOfHops = CalculateTopography(Nodes, MaximumHops);
			_nodeLayers = CalculateNodeLayers(_nodesByNumberOfHops, NodeSelectionHopWindowSize);
			_nodesByDetectedZone = CalculateNodesByDetectedZone(Nodes, maxDetectedZone);
		}
		internal void ReloadMapping(RelayNodeClusterDefinition relayNodeClusterDefinition, RelayNodeConfig newConfig, ForwardingConfig forwardingConfig)
		{
			_minimumId = relayNodeClusterDefinition.MinId;
			_maximumId = relayNodeClusterDefinition.MaxId;
			_mapNetwork = forwardingConfig.MapNetwork;
			
			//figure out if anything changed. if it did, rebuild
			
			bool rebuild = false;

			ushort newLocalZone = newConfig.GetLocalZone();
			if (newLocalZone != _localZone)
			{
				rebuild = true;
				_localZone = newLocalZone;
			}
			else
			{
				if((_zoneDefinitions == null && newConfig.RelayNodeMapping.ZoneDefinitions != null) ||
				(_zoneDefinitions != null && newConfig.RelayNodeMapping.ZoneDefinitions == null) ||
				(_zoneDefinitions != null && !_zoneDefinitions.Equals(newConfig.RelayNodeMapping.ZoneDefinitions)))
				{
					rebuild = true;
					_zoneDefinitions = newConfig.RelayNodeMapping.ZoneDefinitions;
				}
				
			}
			

			int effectiveSize = (!_meInThisCluster ? Nodes.Count : Nodes.Count + 1);
			
			//if there's a different number of nodes, we definitely have to rebuild
			if (relayNodeClusterDefinition.RelayNodes.Length != effectiveSize)
			{
				if(_log.IsInfoEnabled)
					_log.InfoFormat("Number of nodes in a cluster in group {0} changed from {1} to {2}, rebuilding", _nodeGroup.GroupName, effectiveSize, relayNodeClusterDefinition.RelayNodes.Length);				
				rebuild = true;
			}
			else
			{
				//if any of the nodes we do have aren't in the config, rebuild				
				foreach (Node node in Nodes)
				{
					if (!relayNodeClusterDefinition.ContainsNode(node.EndPoint.Address, node.EndPoint.Port))
					{
						if (_log.IsInfoEnabled)
							_log.InfoFormat("Node {0} is no longer found in its cluster in group {1}, rebuilding.",
								node, _nodeGroup.GroupName);
						rebuild = true;						
						break;
					}
				}
				if (!rebuild && _nodeGroup.NodeSelectionHopWindowSize != NodeSelectionHopWindowSize)
				{
					NodeSelectionHopWindowSize = _nodeGroup.NodeSelectionHopWindowSize;
					rebuild = true;                    
				}

				if (!rebuild && _meInThisCluster)
				{
					if (!relayNodeClusterDefinition.ContainsNode(Me.EndPoint.Address, Me.EndPoint.Port))
					{
						if (_log.IsInfoEnabled)
							_log.InfoFormat("Node {0} (this machine) is no longer found in its cluster in group {1}, rebuilding.",
								Me, _nodeGroup.GroupName);
						rebuild = true;						
					}
				}

				//or if there are any nodes in the config that aren't here, rebuild
				if (!rebuild)
				{
					foreach(RelayNodeDefinition nodeDefinition in relayNodeClusterDefinition.RelayNodes)
					{
						if (!ContainsNode(nodeDefinition))
						{
							if (_log.IsInfoEnabled)
								_log.InfoFormat("Node {0} is defined in the new config but does not exist in this cluster in group {1}, rebuilding.",
									nodeDefinition, _nodeGroup.GroupName);
							rebuild = true;
							break;
						}
					}
				}
			}

			if (rebuild)
			{				
				Dictionary<ushort, List<Node>> newZoneNodes = new Dictionary<ushort, List<Node>>();		
				List<Node> newNodes = new List<Node>();

				RelayNodeDefinition meDefinition = newConfig.GetMyNode();
				DispatcherQueue nodeInQueue, nodeOutQueue;
				
				if (meDefinition != null)
				{                    
					GetMessageQueuesFor(meDefinition, relayNodeClusterDefinition,
						NodeManager.Instance.InMessageDispatcher, NodeManager.Instance.OutMessageDispatcher,
						out nodeInQueue, out nodeOutQueue);
					//Me is in the new config
					//Either create it new or overwrite the old one					
					Me = new Node(meDefinition, _nodeGroup, this, forwardingConfig, 
						nodeInQueue, nodeOutQueue);

				}
				else
				{
					//me is NOT in the new config.
					Me = null;
				}
				ushort maxDetectedZone = _localZone;
				foreach (RelayNodeDefinition nodeDefinition in relayNodeClusterDefinition.RelayNodes)
				{					
					if (nodeDefinition != meDefinition)
					{
						GetMessageQueuesFor(nodeDefinition, relayNodeClusterDefinition,
						NodeManager.Instance.InMessageDispatcher, NodeManager.Instance.OutMessageDispatcher,
						out nodeInQueue, out nodeOutQueue);

						Node node = new Node(nodeDefinition, _nodeGroup, this, forwardingConfig,
							nodeInQueue, nodeOutQueue);

						newNodes.Add(node);
						if (node.DetectedZone > maxDetectedZone)
						{
							maxDetectedZone = node.DetectedZone;
						}
						if (node.Zone > maxDetectedZone)
						{
							maxDetectedZone = node.Zone;
						}
						if (!newZoneNodes.ContainsKey(nodeDefinition.Zone))
						{
							newZoneNodes[nodeDefinition.Zone] = new List<Node>();
						}

						newZoneNodes[nodeDefinition.Zone].Add(node);

					}
				}
				Nodes = newNodes;
				ZoneNodes = newZoneNodes;
				_nodesByNumberOfHops = CalculateTopography(Nodes, MaximumHops);                
				_nodeLayers = CalculateNodeLayers(_nodesByNumberOfHops, NodeSelectionHopWindowSize);
				_nodesByDetectedZone = CalculateNodesByDetectedZone(Nodes, maxDetectedZone);
				lock (_chooseLock)
				{
					ChosenNode = null;
				}
				ChosenZoneNodes = new Dictionary<ushort, Node>();
			}
			else
			{	
				//just reload the configs to get any new network or queue settings
				bool hitMe = false;
				string meString = String.Empty;
				if (Me != null)
				{
					meString = Me.ToString();
				}
				for (int i = 0; i < relayNodeClusterDefinition.RelayNodes.Length; i++)
				{
					string definitionString = relayNodeClusterDefinition.RelayNodes[i].Host + ":" + relayNodeClusterDefinition.RelayNodes[i].Port;
					if (definitionString == meString)
					{
						hitMe = true;
						Me.ReloadMapping(relayNodeClusterDefinition.RelayNodes[i], forwardingConfig);
					}
					else
					{						
						Nodes[(hitMe ? i - 1 : i)].ReloadMapping(relayNodeClusterDefinition.RelayNodes[i],forwardingConfig);						
					}
				}
				lock (_chooseLock)
				{
					ChosenNode = null;
				}
			}
		}