Exemple #1
0
        private void GetConfig()
        {
            EventHandler reloadEventHandler = ReloadConfig;

            configuration = RelayNodeConfig.GetRelayNodeConfig(reloadEventHandler);

            if (configuration != null)
            {
                if (configuration.GetMyNode() != null)
                {
                    MyZone = configuration.GetMyNode().Zone;
                }

                instanceName = configuration.InstanceName;
                if (configuration.TransportSettings != null)
                {
                    portNumber     = configuration.TransportSettings.ListenPort;
                    httpPortNumber = configuration.TransportSettings.HttpListenPort;
                }
            }
            else
            {
                if (log.IsErrorEnabled)
                {
                    log.Error("NO CONFIG SECTION FOUND, SERVICE NOT STARTING.");
                }
            }
        }
Exemple #2
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);
        }
Exemple #3
0
        private int GetResetDuration()
        {
            var resetDuration = 0;
            // node
            var node = configuration.GetMyNode();

            if (node == null)
            {
                return(resetDuration);
            }
            resetDuration = node.StartupRepopulateDuration;
            if (resetDuration != 0)
            {
                return(resetDuration);
            }
            // cluster
            var cluster = configuration.GetMyCluster();

            if (cluster == null)
            {
                return(resetDuration);
            }
            resetDuration = cluster.StartupRepopulateDuration;
            if (resetDuration != 0)
            {
                return(resetDuration);
            }
            // group
            var group = configuration.GetMyGroup();

            if (group == null)
            {
                return(resetDuration);
            }
            resetDuration = group.StartupRepopulateDuration;
            return(resetDuration);
        }
		internal void ReloadConfig(RelayNodeConfig newConfiguration)
		{
			if (newConfiguration != null)
			{
                if (log.IsInfoEnabled)
                    log.Info("Reloading configs.");

				fatalFailureTimeout = newConfiguration.FatalShutdownTimeout < 0
					? TimeSpan.FromMinutes(5)
					: TimeSpan.FromSeconds(newConfiguration.FatalShutdownTimeout);

				if (newConfiguration.GetMyNode() != null)
				{
					MyZone = newConfiguration.GetMyNode().Zone;
				}

				SetClusterAddresses(newConfiguration);
				
				messageTracer.ReloadConfig(newConfiguration.TypeSettings.MaxTypeId, newConfiguration.TraceSettings);
				messageTracer.Activated = newConfiguration.OutputTraceInfo;

				//TODO: handle changes in component definition
				components.ReloadConfig(newConfiguration, newConfiguration.IgnoredMessageTypes);

				if (newConfiguration.TransportSettings != null)  
				{
                    if(newConfiguration.TransportSettings.ListenPort != portNumber)
                    {
                    	log.InfoFormat("Changing Socket Transport Port to {0}",
                    		               newConfiguration.TransportSettings.ListenPort);
                    	portNumber = newConfiguration.TransportSettings.ListenPort;
                    	SocketServerAdapter.ChangePort(portNumber);
                    }
					if(newConfiguration.TransportSettings.HttpListenPort != httpPortNumber)
					{
						if (httpPortNumber < 1 && newConfiguration.TransportSettings.HttpListenPort > 0) //there was no http server and now we want one
						{
							httpPortNumber = newConfiguration.TransportSettings.HttpListenPort;
							StartHttpServer();

						}
						else if (newConfiguration.TransportSettings.HttpListenPort < 1 && httpPortNumber > 0) //shut off a running server
						{
							httpPortNumber = newConfiguration.TransportSettings.HttpListenPort;
							StopHttpServer();
						}
						else //just change the port on an existing server
						{
							log.InfoFormat("Changing Http Transport Port to {0}",
											   newConfiguration.TransportSettings.HttpListenPort);
							httpPortNumber = newConfiguration.TransportSettings.HttpListenPort;
							_httpServer.ChangePort(httpPortNumber);	
						}
						
					}
				}

				if (newConfiguration.NumberOfThreads != configuration.NumberOfThreads)
				{
					if(log.IsInfoEnabled)
                        log.InfoFormat("Changing number of relay node threads from {0} to {1}", 
                            configuration.NumberOfThreads, newConfiguration.NumberOfThreads);
					try
					{
						Dispatcher oldInDispatcher = inDispatcher;
						Dispatcher newInDispatcher;
						const string inThreadsName = "DataRelayNode";
						if (newConfiguration.NumberOfThreads > 0)
						{
							newInDispatcher = new Dispatcher(newConfiguration.NumberOfThreads, ThreadPriority.Normal, true, inThreadsName);
						}
						else
						{
							newInDispatcher = new Dispatcher() { Name = inThreadsName };
						}

						DispatcherQueue newInQueue = new DispatcherQueue("DataRelayDispatcherQueue", newInDispatcher, TaskExecutionPolicy.ConstrainQueueDepthThrottleExecution, newConfiguration.MaximumMessageQueueDepth);

						Interlocked.Exchange(ref inMessagePort, new Port<RelayMessage>());
						Interlocked.Exchange(ref inMessageWithContextPort, new Port<RelayMessageWithContext>());
						Interlocked.Exchange(ref inMessagesPort, new Port<IList<RelayMessage>>());

						Arbiter.Activate(newInQueue,
							 Arbiter.Receive<RelayMessage>(true, inMessagePort, HandleInMessage));
						Arbiter.Activate(newInQueue,
							 Arbiter.Receive<RelayMessageWithContext>(true, inMessageWithContextPort, HandleInMessage));
						Arbiter.Activate(newInQueue,
							 Arbiter.Receive<IList<RelayMessage>>(true, inMessagesPort, HandleInMessages));

						inMessageQueue = newInQueue;
						inDispatcher = newInDispatcher;
						oldInDispatcher.Dispose();
					}
					catch (Exception e)
					{
                        if (log.IsErrorEnabled)
                            log.ErrorFormat("Error changing number of relay node threads: {0}", e);
					}
				}
				else
				{
					//not rebuilding the queue, but reset its max queue depth anyway
					inMessageQueue.MaximumQueueDepth = newConfiguration.MaximumMessageQueueDepth;
				}

				SetupOutMessagesOnRelayThreads(newConfiguration);

				queuedTaskThreshold = (int)Math.Floor(0.9 * newConfiguration.MaximumMessageQueueDepth);
				configuration = newConfiguration;
                if (log.IsInfoEnabled)
                    log.Info("Done Reloading configs.");
			}
			else
			{
                if (log.IsErrorEnabled)
                    log.Error("Attempt to reload null config");
			}
		}
		private void GetConfig()
		{
			EventHandler reloadEventHandler = ReloadConfig;
			configuration = RelayNodeConfig.GetRelayNodeConfig(reloadEventHandler);
			
			if (configuration != null)
			{
				if (configuration.GetMyNode() != null)
				{
					MyZone = configuration.GetMyNode().Zone;
				}

				instanceName = configuration.InstanceName;
				if (configuration.TransportSettings != null)
				{
					portNumber = configuration.TransportSettings.ListenPort;
					httpPortNumber = configuration.TransportSettings.HttpListenPort;
				}

			}
			else
			{
                if (log.IsErrorEnabled)
                    log.Error("NO CONFIG SECTION FOUND, SERVICE NOT STARTING.");
			}
		}
Exemple #6
0
        internal void ReloadConfig(RelayNodeConfig newConfiguration)
        {
            if (newConfiguration != null)
            {
                if (log.IsInfoEnabled)
                {
                    log.Info("Reloading configs.");
                }

                fatalFailureTimeout = newConfiguration.FatalShutdownTimeout < 0
                                        ? TimeSpan.FromMinutes(5)
                                        : TimeSpan.FromSeconds(newConfiguration.FatalShutdownTimeout);

                if (newConfiguration.GetMyNode() != null)
                {
                    MyZone = newConfiguration.GetMyNode().Zone;
                }

                SetClusterAddresses(newConfiguration);

                messageTracer.ReloadConfig(newConfiguration.TypeSettings.MaxTypeId, newConfiguration.TraceSettings);
                messageTracer.Activated = newConfiguration.OutputTraceInfo;

                //TODO: handle changes in component definition
                components.ReloadConfig(newConfiguration, newConfiguration.IgnoredMessageTypes);

                if (newConfiguration.TransportSettings != null)
                {
                    if (newConfiguration.TransportSettings.ListenPort != portNumber)
                    {
                        log.InfoFormat("Changing Socket Transport Port to {0}",
                                       newConfiguration.TransportSettings.ListenPort);
                        portNumber = newConfiguration.TransportSettings.ListenPort;
                        SocketServerAdapter.ChangePort(portNumber);
                    }
                    if (newConfiguration.TransportSettings.HttpListenPort != httpPortNumber)
                    {
                        if (httpPortNumber < 1 && newConfiguration.TransportSettings.HttpListenPort > 0)                         //there was no http server and now we want one
                        {
                            httpPortNumber = newConfiguration.TransportSettings.HttpListenPort;
                            StartHttpServer();
                        }
                        else if (newConfiguration.TransportSettings.HttpListenPort < 1 && httpPortNumber > 0)                         //shut off a running server
                        {
                            httpPortNumber = newConfiguration.TransportSettings.HttpListenPort;
                            StopHttpServer();
                        }
                        else                         //just change the port on an existing server
                        {
                            log.InfoFormat("Changing Http Transport Port to {0}",
                                           newConfiguration.TransportSettings.HttpListenPort);
                            httpPortNumber = newConfiguration.TransportSettings.HttpListenPort;
                            _httpServer.ChangePort(httpPortNumber);
                        }
                    }
                }

                if (newConfiguration.NumberOfThreads != configuration.NumberOfThreads)
                {
                    if (log.IsInfoEnabled)
                    {
                        log.InfoFormat("Changing number of relay node threads from {0} to {1}",
                                       configuration.NumberOfThreads, newConfiguration.NumberOfThreads);
                    }
                    try
                    {
                        Dispatcher   oldInDispatcher = inDispatcher;
                        Dispatcher   newInDispatcher;
                        const string inThreadsName = "DataRelayNode";
                        if (newConfiguration.NumberOfThreads > 0)
                        {
                            newInDispatcher = new Dispatcher(newConfiguration.NumberOfThreads, ThreadPriority.Normal, true, inThreadsName);
                        }
                        else
                        {
                            newInDispatcher = new Dispatcher()
                            {
                                Name = inThreadsName
                            };
                        }

                        DispatcherQueue newInQueue = new DispatcherQueue("DataRelayDispatcherQueue", newInDispatcher, TaskExecutionPolicy.ConstrainQueueDepthThrottleExecution, newConfiguration.MaximumMessageQueueDepth);

                        Interlocked.Exchange(ref inMessagePort, new Port <RelayMessage>());
                        Interlocked.Exchange(ref inMessageWithContextPort, new Port <RelayMessageWithContext>());
                        Interlocked.Exchange(ref inMessagesPort, new Port <IList <RelayMessage> >());

                        Arbiter.Activate(newInQueue,
                                         Arbiter.Receive <RelayMessage>(true, inMessagePort, HandleInMessage));
                        Arbiter.Activate(newInQueue,
                                         Arbiter.Receive <RelayMessageWithContext>(true, inMessageWithContextPort, HandleInMessage));
                        Arbiter.Activate(newInQueue,
                                         Arbiter.Receive <IList <RelayMessage> >(true, inMessagesPort, HandleInMessages));

                        inMessageQueue = newInQueue;
                        inDispatcher   = newInDispatcher;
                        oldInDispatcher.Dispose();
                    }
                    catch (Exception e)
                    {
                        if (log.IsErrorEnabled)
                        {
                            log.ErrorFormat("Error changing number of relay node threads: {0}", e);
                        }
                    }
                }
                else
                {
                    //not rebuilding the queue, but reset its max queue depth anyway
                    inMessageQueue.MaximumQueueDepth = newConfiguration.MaximumMessageQueueDepth;
                }

                SetupOutMessagesOnRelayThreads(newConfiguration);

                queuedTaskThreshold = (int)Math.Floor(0.9 * newConfiguration.MaximumMessageQueueDepth);
                configuration       = newConfiguration;
                if (log.IsInfoEnabled)
                {
                    log.Info("Done Reloading configs.");
                }
            }
            else
            {
                if (log.IsErrorEnabled)
                {
                    log.Error("Attempt to reload null config");
                }
            }
        }
Exemple #7
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);
        }
Exemple #8
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 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;
				}
			}
		}