private void InitializeInstance(RelayNodeConfig config, ForwardingConfig forwardingConfig, Dictionary <string, Dictionary <string, MessageQueue> > errorQueues)
        {
            Counters = new ForwardingCounters();

            if (config != null)
            {
                //without this we'll get a null ref exception
                if (forwardingConfig == null)
                {
                    throw new ArgumentNullException("forwardingConfig", "Requires a forwardingConfig to initialize");
                }

                Config           = config;
                ForwardingConfig = forwardingConfig;
                _zoneDefinitions = config.RelayNodeMapping.ZoneDefinitions;
                Counters.Initialize(Config.InstanceName);

                if (InMessageDispatcher != null)
                {
                    if (_log.IsInfoEnabled)
                    {
                        _log.Info("Relay Forwarder Node Manager Initialized with non-null Dispatcher.");
                    }
                }
                else
                {
                    InMessageDispatcher = new Dispatcher(forwardingConfig.NumberOfThreads, ThreadPriority.Normal, true, "Relay Forwarder");
                }

                if (OutMessageDispatcher == null)
                {
                    OutMessageDispatcher = new Dispatcher(forwardingConfig.NumberOfOutMessageThreads, ThreadPriority.Normal, true, "Relay Forwader Out Messages");
                }

                NodeGroup.MaximumQueuedItems = forwardingConfig.MaximumTaskQueueDepth;

                BuildNodeGroups(config, errorQueues);

                if (config.MyAddresses != null && config.MyAddresses.Count > 0)
                {
                    for (int i = 0; i < config.MyAddresses.Count; i++)
                    {
                        AddressFamily family = config.MyAddresses[i].AddressFamily;
                        if (family == AddressFamily.InterNetwork &&
                            !IPAddress.Loopback.Equals(config.MyAddresses[i])
                            )
                        {
                            MyIpAddress = config.MyAddresses[i];
                            break;
                        }
                    }
                }

                _queuedMessageCounterTimer = new Timer(CountQueuedMessages, null, 5000, 5000);

                _aggregateCounterTickTimer = new Timer(AggregateCounterTicker, null, 500, 500);
                _myNodeDefinition          = GetMyNodeDefinition();
            }
        }
Beispiel #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);
        }
Beispiel #3
0
        private void InitializeInstance(RelayNodeConfig config, ForwardingConfig forwardingConfig, Dictionary <string, Dictionary <string, ErrorQueue> > errorQueues)
        {
            Counters = new ForwardingCounters();

            if (config != null)
            {
                //without this we'll get a null ref exception
                if (forwardingConfig == null)
                {
                    throw new ArgumentNullException("forwardingConfig", "Requires a forwardingConfig to initialize");
                }

                Config           = config;
                ForwardingConfig = forwardingConfig;
                _zoneDefinitions = config.RelayNodeMapping.ZoneDefinitions;
                Counters.Initialize(Config.InstanceName);

                ExtractCommonConfigValues(forwardingConfig);

                if (InMessageDispatcher != null)
                {
                    if (_log.IsInfoEnabled)
                    {
                        _log.Info("Relay Forwarder Node Manager Initialized with non-null Dispatcher.");
                    }
                }
                else
                {
                    InMessageDispatcher = new Dispatcher(forwardingConfig.NumberOfThreads, ThreadPriority.Normal, true, "Relay Forwarder");
                }

                if (OutMessageDispatcher == null)
                {
                    OutMessageDispatcher = new Dispatcher(forwardingConfig.NumberOfOutMessageThreads, ThreadPriority.Normal, true, "Relay Forwader Out Messages");
                }



                BuildNodeGroups(config, errorQueues);

                MyIpAddress = config.GetAddressToUse();

                _queuedMessageCounterTimer = new Timer(CountQueuedMessages, null, 5000, 5000);

                _aggregateCounterTickTimer = new Timer(AggregateCounterTicker, null, 500, 500);
                _myNodeDefinition          = GetMyNodeDefinition();
                _myZone = Node.DetermineZone(_myNodeDefinition);
            }
        }
Beispiel #4
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 #5
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;
                }
            }
        }
		private void InitializeInstance(RelayNodeConfig config, ForwardingConfig forwardingConfig, Dictionary<string, Dictionary<string, MessageQueue>> errorQueues)
		{
			Counters = new ForwardingCounters();

			if (config != null)
			{
				//without this we'll get a null ref exception
				if (forwardingConfig == null) throw new ArgumentNullException("forwardingConfig", "Requires a forwardingConfig to initialize");
				  
				Config = config;
				ForwardingConfig = forwardingConfig;
				_zoneDefinitions = config.RelayNodeMapping.ZoneDefinitions;		
				Counters.Initialize(Config.InstanceName);

				if (InMessageDispatcher != null)
				{
					if (_log.IsInfoEnabled)
						_log.Info("Relay Forwarder Node Manager Initialized with non-null Dispatcher.");                    
				}
				else
				{
					InMessageDispatcher = new Dispatcher(forwardingConfig.NumberOfThreads, ThreadPriority.Normal, true, "Relay Forwarder");
				}

				if (OutMessageDispatcher == null)
				{
					OutMessageDispatcher = new Dispatcher(forwardingConfig.NumberOfOutMessageThreads, ThreadPriority.Normal, true, "Relay Forwader Out Messages");
				}
				
				NodeGroup.MaximumQueuedItems = forwardingConfig.MaximumTaskQueueDepth;

				BuildNodeGroups(config, errorQueues);

				if (config.MyAddresses != null && config.MyAddresses.Count > 0)
				{	
					for (int i = 0; i < config.MyAddresses.Count; i++)
					{
						AddressFamily family = config.MyAddresses[i].AddressFamily;
						if (family == AddressFamily.InterNetwork &&
							!IPAddress.Loopback.Equals(config.MyAddresses[i])
							)
						{
							MyIpAddress = config.MyAddresses[i];
							break;
						}
					}
				}

				_queuedMessageCounterTimer = new Timer(CountQueuedMessages, null, 5000, 5000);

				_aggregateCounterTickTimer = new Timer(AggregateCounterTicker, null, 500, 500);
				_myNodeDefinition = GetMyNodeDefinition();
			}
		}
		internal void ReloadConfig(RelayNodeConfig config, ForwardingConfig newForwardingConfig)
		{

			if (config.RelayNodeMapping == null)
			{
				if (_log.IsErrorEnabled)
					_log.Error("Got new config with no defined groups.");
			}
			else
			{
				if (config.RelayNodeMapping.Validate())
				{
					_zoneDefinitions = config.RelayNodeMapping.ZoneDefinitions;	//make sure this is set before reloading the mapping so any changes propogate	
					Dictionary<string, Dictionary<string, MessageQueue>> errorQueues = GetErrorQueues();
					NodeGroups.ReloadMapping(config, newForwardingConfig);
					//note that if a node changes groups, the error queue won't make it!
					NodeGroups.PopulateQueues(errorQueues, false);
				}
				else
				{
					if (_log.IsErrorEnabled)
						_log.Error("Forwarder not reloading invalid config.");
				}
			}

			Config = config;

			_myNodeDefinition = GetMyNodeDefinition();
			bool doNewInDispatcher, doNewOutDispatcher;
			if (newForwardingConfig.NumberOfThreads != ForwardingConfig.NumberOfThreads)
			{
				doNewInDispatcher = true;
			}
			else
			{
				doNewInDispatcher = false;
			}
			if (newForwardingConfig.NumberOfOutMessageThreads != ForwardingConfig.NumberOfOutMessageThreads)
			{
				doNewOutDispatcher = true;
			}
			else
			{
				doNewOutDispatcher = false;
			}


			if (doNewInDispatcher || doNewOutDispatcher)
			{
				Dispatcher oldInDispatcher = null, newInDispatcher, oldOutDispatcher = null, newOutDispatcher;

				if (doNewInDispatcher)
				{
					if (_log.IsInfoEnabled)
						_log.InfoFormat("Changing number of messaging threads from {0} to {1}", ForwardingConfig.NumberOfThreads, newForwardingConfig.NumberOfThreads);
					oldInDispatcher = InMessageDispatcher;
					newInDispatcher = new Dispatcher(newForwardingConfig.NumberOfThreads, ThreadPriority.Normal, true, "Relay Forwarder");

				}
				else
				{
					newInDispatcher = InMessageDispatcher;
				}
				if (doNewOutDispatcher)
				{
					if (_log.IsInfoEnabled)
						_log.InfoFormat("Changing number of out message threads from {0} to {1}", ForwardingConfig.NumberOfOutMessageThreads, newForwardingConfig.NumberOfOutMessageThreads);
					oldOutDispatcher = OutMessageDispatcher;
					newOutDispatcher = new Dispatcher(newForwardingConfig.NumberOfOutMessageThreads, ThreadPriority.Normal, true, "Relay Forwarder");
				}
				else
				{
					newOutDispatcher = OutMessageDispatcher;
				}

				InMessageDispatcher = newInDispatcher;
				OutMessageDispatcher = newOutDispatcher;

				NodeGroups.SetNewDispatchers(newInDispatcher, newOutDispatcher);

				ForwardingConfig = newForwardingConfig;

				if (doNewInDispatcher)
				{
					if (_log.IsInfoEnabled)
						_log.Info("Disposing old in message Dispatcher");
					oldInDispatcher.Dispose();
				}
				if (doNewOutDispatcher)
				{
					if (_log.IsInfoEnabled)
						_log.Info("Disposing old out message Dispatcher");
					oldOutDispatcher.Dispose();
				}
			}
			else
			{
				ForwardingConfig = newForwardingConfig;
			}
		}
        internal void ReloadConfig(RelayNodeConfig config, ForwardingConfig newForwardingConfig)
        {
            if (config.RelayNodeMapping == null)
            {
                if (_log.IsErrorEnabled)
                {
                    _log.Error("Got new config with no defined groups.");
                }
            }
            else
            {
                if (config.RelayNodeMapping.Validate())
                {
                    _zoneDefinitions = config.RelayNodeMapping.ZoneDefinitions;                         //make sure this is set before reloading the mapping so any changes propogate
                    Dictionary <string, Dictionary <string, MessageQueue> > errorQueues = GetErrorQueues();
                    NodeGroups.ReloadMapping(config, newForwardingConfig);
                    //note that if a node changes groups, the error queue won't make it!
                    NodeGroups.PopulateQueues(errorQueues, false);
                }
                else
                {
                    if (_log.IsErrorEnabled)
                    {
                        _log.Error("Forwarder not reloading invalid config.");
                    }
                }
            }

            Config = config;

            _myNodeDefinition = GetMyNodeDefinition();
            bool doNewInDispatcher, doNewOutDispatcher;

            if (newForwardingConfig.NumberOfThreads != ForwardingConfig.NumberOfThreads)
            {
                doNewInDispatcher = true;
            }
            else
            {
                doNewInDispatcher = false;
            }
            if (newForwardingConfig.NumberOfOutMessageThreads != ForwardingConfig.NumberOfOutMessageThreads)
            {
                doNewOutDispatcher = true;
            }
            else
            {
                doNewOutDispatcher = false;
            }


            if (doNewInDispatcher || doNewOutDispatcher)
            {
                Dispatcher oldInDispatcher = null, newInDispatcher, oldOutDispatcher = null, newOutDispatcher;

                if (doNewInDispatcher)
                {
                    if (_log.IsInfoEnabled)
                    {
                        _log.InfoFormat("Changing number of messaging threads from {0} to {1}", ForwardingConfig.NumberOfThreads, newForwardingConfig.NumberOfThreads);
                    }
                    oldInDispatcher = InMessageDispatcher;
                    newInDispatcher = new Dispatcher(newForwardingConfig.NumberOfThreads, ThreadPriority.Normal, true, "Relay Forwarder");
                }
                else
                {
                    newInDispatcher = InMessageDispatcher;
                }
                if (doNewOutDispatcher)
                {
                    if (_log.IsInfoEnabled)
                    {
                        _log.InfoFormat("Changing number of out message threads from {0} to {1}", ForwardingConfig.NumberOfOutMessageThreads, newForwardingConfig.NumberOfOutMessageThreads);
                    }
                    oldOutDispatcher = OutMessageDispatcher;
                    newOutDispatcher = new Dispatcher(newForwardingConfig.NumberOfOutMessageThreads, ThreadPriority.Normal, true, "Relay Forwarder");
                }
                else
                {
                    newOutDispatcher = OutMessageDispatcher;
                }

                InMessageDispatcher  = newInDispatcher;
                OutMessageDispatcher = newOutDispatcher;

                NodeGroups.SetNewDispatchers(newInDispatcher, newOutDispatcher);

                ForwardingConfig = newForwardingConfig;

                if (doNewInDispatcher)
                {
                    if (_log.IsInfoEnabled)
                    {
                        _log.Info("Disposing old in message Dispatcher");
                    }
                    oldInDispatcher.Dispose();
                }
                if (doNewOutDispatcher)
                {
                    if (_log.IsInfoEnabled)
                    {
                        _log.Info("Disposing old out message Dispatcher");
                    }
                    oldOutDispatcher.Dispose();
                }
            }
            else
            {
                ForwardingConfig = newForwardingConfig;
            }
        }
		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;
				}
			}
		}