public RelayNodeDefinition GetMyNode() { if (!lookedForNode) { lock (myNodeLock) { if (!lookedForNode) { RelayNodeGroupDefinition group = GetMyGroup(); if (group != null) { int portNumber; List <IPAddress> addresses; GetMyNetworkInfo(out addresses, out portNumber); if (portNumber != 0 && addresses != null) { foreach (IPAddress address in addresses) { myNode = group.GetNodeFor(address, portNumber); if (myNode != null) { break; } } } } lookedForNode = true; } } } return(myNode); }
public SocketTransportAdapter(RelayNodeDefinition node, RelayNodeGroupDefinition group, int chunkLength) { this.node = node; this.defaultChunkLength = chunkLength; LoadSettings(node, group); }
private void _receiveMessageList(IList <RelayMessage> messages, RelayNodeDefinition nodeDefinition, RelayNodeGroupDefinition groupDefinition) { foreach (var component in _components) { component.HandleMessages(messages); } }
public void LoadSettings(RelayNodeDefinition node, RelayNodeGroupDefinition group) { MySpace.SocketTransport.SocketSettings newSettings = BuildSettings(group.SocketSettings); if (newSettings.SameAs(settings)) return; IDisposable disposableObject = null; try { settings = newSettings; socketClient = new SocketClient(node.IPEndPoint, settings); disposableObject = asyncSocketClient; asyncSocketClient = new AsyncSocketClient(node.IPEndPoint, new SocketPoolConfig { ReceiveTimeout = settings.ReceiveTimeout, NetworkOrdered = settings.UseNetworkOrder, ConnectTimeout = settings.ConnectTimeout, LoanCapacity = settings.PoolSize }); } finally { if (disposableObject != null) { try { asyncSocketClient.Dispose(); } catch (Exception ex) { log.Error("Failed to dispose AsyncSocketClient", ex); } } } }
private IRelayTransport _createTransportDelegate(RelayNodeDefinition nodeDefinition, RelayNodeGroupDefinition groupDefinition) { var transport = new MockTransport(nodeDefinition, groupDefinition); transport.DoDispatchMessages = true; transport.MessageRecievedMethod = _receiveMessage; transport.MessageListRecievedMethod = _receiveMessageList; IRelayTransport[] otherTransports = null; if (_createTransports != null) { var count = _createTransports.Length; if (count > 0) { otherTransports = new IRelayTransport[count]; for (var idx = 0; idx < count; ++idx) { otherTransports[idx] = _createTransports[idx]( nodeDefinition, groupDefinition); } } } if (otherTransports == null) { return(transport); } var transports = new List <IRelayTransport>(); transports.AddRange(otherTransports); transports.Add(transport); return(new RelayTransportStack(transports.ToArray())); }
private void _receiveMessage(RelayMessage message, RelayNodeDefinition nodeDefinition, RelayNodeGroupDefinition groupDefinition) { foreach (var component in _components) { component.HandleMessage(message); } }
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 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); }
/// <summary> /// Creates a new instance of <see cref="IRelayTransport"/> for the given <see cref="RelayNodeDefinition"/> /// and <see cref="RelayNodeGroupDefinition"/>. /// </summary> /// <param name="nodeDefinition">The node definition.</param> /// <param name="group">The group.</param> /// <param name="chunkLength">The chunk length</param> /// <returns></returns> internal static IRelayTransport CreateTransportForNode(RelayNodeDefinition nodeDefinition, RelayNodeGroupDefinition group, int chunkLength) { CreateTransportDelegate creator = CreateTransportMethod; if (creator == null) { return new SocketTransportAdapter(nodeDefinition, group, chunkLength); } IRelayTransport transport = creator(nodeDefinition, group) ?? new NullTransport(); return transport; }
/// <summary> /// Creates a new instance of <see cref="IRelayTransport"/> for the given <see cref="RelayNodeDefinition"/> /// and <see cref="RelayNodeGroupDefinition"/>. /// </summary> /// <param name="nodeDefinition">The node definition.</param> /// <param name="group">The group.</param> /// <param name="chunkLength">The chunk length</param> /// <returns></returns> internal static IRelayTransport CreateTransportForNode(RelayNodeDefinition nodeDefinition, RelayNodeGroupDefinition group, int chunkLength) { CreateTransportDelegate creator = CreateTransportMethod; if (creator == null) { return(new SocketTransportAdapter(nodeDefinition, group, chunkLength)); } IRelayTransport transport = creator(nodeDefinition, group) ?? new NullTransport(); return(transport); }
internal Node(RelayNodeDefinition nodeDefinition, NodeGroup ownerGroup, NodeCluster ownerCluster, ForwardingConfig forwardingConfig, DispatcherQueue inMessageQueue, DispatcherQueue outMessageQueue) { DetectedZone = 0; NodeDefinition = nodeDefinition; NodeGroup = ownerGroup; NodeCluster = ownerCluster; _messageCounts = new int[RelayMessage.NumberOfTypes]; _lastMessageTimes = new double[RelayMessage.NumberOfTypes]; _averageMessageTimes = new double[RelayMessage.NumberOfTypes]; if (EndPoint != null) { _transport = TransportFactory.CreateTransportForNode(nodeDefinition, ownerGroup.GroupDefinition, forwardingConfig.MessageChunkLength); DetectedZone = NodeManager.Instance.GetZoneForAddress(EndPoint.Address); if (forwardingConfig.MapNetwork) { HopsFromHere = HowManyHopsFromHere(); } else { HopsFromHere = 0; } } else { _transport = new NullTransport(); } _inMessageQueue = inMessageQueue; _outMessageQueue = outMessageQueue; if (forwardingConfig != null) { _messageBurstLength = forwardingConfig.MessageBurstLength; _messageBurstTimeout = forwardingConfig.MessageBurstTimeout; _messageBurstTimeoutSpan = TimeSpan.FromMilliseconds(_messageBurstTimeout); MessageErrorQueue = new MessageQueue(ownerGroup.GetQueueConfig()); _repostMessageLists = forwardingConfig.RepostMessageLists; } ActivateBurstReceive(1); //the burst length will be used after the first message is received // async, no skipping of the error queue (duh) Arbiter.Activate(_inMessageQueue, Arbiter.Receive<List<SerializedRelayMessage>>(true, _inMessagesPort, messages => DoHandleInMessages(messages, false))); Arbiter.Activate(_outMessageQueue, Arbiter.Receive<MessagesWithLock>(true, _outMessagesPort, delegate(MessagesWithLock messages) { HandleOutMessages(messages.Messages); messages.Locker.Decrement(); })); }
/// <summary> /// this (or <see cref="ReloadConfig"/>) gets called (depending) when the TypeSettings.Config file /// are changed. /// </summary> /// <remarks> /// Added: craigbro /// cachedTypeSettings now held with the forwarder for reference of /// exceptions on Synchronous "in" messages. /// To reload, we just null out the cached TypeSettingsCollection object and the /// accessor will reload it on next call /// While ConfigurationManager.GetSection is quite performant after the 1st hit, /// keeping them cached is about twice as fast. /// </remarks> /// <param name="config"></param> /// <param name="runState"></param> private void LoadConfig(RelayNodeConfig config, ComponentRunState runState) { if (config != null) { if (config.RelayComponents != null) { object configObject = config.RelayComponents.GetConfigFor(GetComponentName()); ForwardingConfig forwardingConfig = configObject as ForwardingConfig; if (forwardingConfig == null) { if (log.IsInfoEnabled) { log.Info("No forwarding configuration supplied. Using defaults."); } forwardingConfig = new ForwardingConfig(); } NodeManager.Initialize(config, forwardingConfig, GetErrorQueues(runState)); TypeSettingCollection typeSettingCollection = null; if (NodeManager.Instance.Config != null) { if (NodeManager.Instance.Config.TypeSettings != null) { typeSettingCollection = NodeManager.Instance.Config.TypeSettings.TypeSettingCollection; } } TypeSpecificStatisticsManager.Initialize(typeSettingCollection); _enableAsyncBulkGets = forwardingConfig.EnableAsyncBulkGets; _myNodeDefinition = NodeManager.Instance.GetMyNodeDefinition(); _myZone = Node.DetermineZone(_myNodeDefinition); short maxTypeId = 0; if (config.TypeSettings != null) { maxTypeId = config.TypeSettings.MaxTypeId; } DebugWriter.SetTraceSettings(maxTypeId, forwardingConfig.TraceSettings); DebugWriter.WriteCallingMethod = forwardingConfig.WriteCallingMethod; DebugWriter.WriteMessageTrace = forwardingConfig.WriteMessageTrace; } else { NodeManager.Initialize(null, null, null); TypeSpecificStatisticsManager.Initialize(null); } } else { NodeManager.Initialize(null, null, null); TypeSpecificStatisticsManager.Initialize(null); } }
/// <summary> /// this (or <see cref="LoadConfig"/>) gets called (depending) when the TypeSettings.Config file /// are changed. /// </summary> /// <remarks> /// Added: craigbro /// cachedTypeSettings now held with the forwarder for reference of /// exceptions on Synchronous "in" messages. /// To reload, we just null out the cached TypeSettingsCollection object and the /// accessor will reload it on next call /// While ConfigurationManager.GetSection is quite performant after the 1st hit, /// keeping them cached is about twice as fast. /// </remarks> /// <param name="config">The config to reload</param> public void ReloadConfig(RelayNodeConfig config) { lock (reloadLock) { if (config != null) { try { object configObject = config.RelayComponents.GetConfigFor(GetComponentName()); ForwardingConfig forwardingConfig = configObject as ForwardingConfig; if (forwardingConfig == null) { if (log.IsInfoEnabled) { log.InfoFormat("No forwarding configuration supplied. Reloading using defaults."); } forwardingConfig = new ForwardingConfig(); } NodeManager.Instance.ReloadConfig(config, forwardingConfig); if (NodeManager.Instance.Config != null) { if (NodeManager.Instance.Config.TypeSettings != null) { TypeSpecificStatisticsManager.Instance.ReloadMapping( NodeManager.Instance.Config.TypeSettings.TypeSettingCollection); } } _enableAsyncBulkGets = forwardingConfig.EnableAsyncBulkGets; _myNodeDefinition = NodeManager.Instance.GetMyNodeDefinition(); _myZone = Node.DetermineZone(_myNodeDefinition); short maxTypeId = 0; if (config.TypeSettings != null) { maxTypeId = config.TypeSettings.MaxTypeId; } DebugWriter.SetTraceSettings(maxTypeId, forwardingConfig.TraceSettings); DebugWriter.WriteCallingMethod = forwardingConfig.WriteCallingMethod; DebugWriter.WriteMessageTrace = forwardingConfig.WriteMessageTrace; } catch (Exception ex) { if (log.IsErrorEnabled) { log.ErrorFormat("Exception reloading config: {0}", ex); } } } } }
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); } }
/// <summary>Initializes an instance of the <see cref="MockTransport"/> class.</summary> /// <param name="nodeDefinition">The node definition.</param> /// <param name="groupDefinition">The group definition.</param> public MockTransport(RelayNodeDefinition nodeDefinition, RelayNodeGroupDefinition groupDefinition) { if (nodeDefinition == null) { throw new ArgumentNullException("nodeDefinition"); } if (groupDefinition == null) { throw new ArgumentNullException("groupDefinition"); } _node = nodeDefinition; _group = groupDefinition; DoDispatchMessages = true; }
public SocketTransportSender(RelayNodeDefinition nodeDefinition, RelayNodeGroupDefinition groupDefinition) { if (groupDefinition.SocketSettings != null) { _sendTimeout = TimeSpan.FromMilliseconds(groupDefinition.SocketSettings.SendTimeout); } else if (groupDefinition.DefaultSocketSettings != null) { _sendTimeout = TimeSpan.FromMilliseconds(groupDefinition.DefaultSocketSettings.SendTimeout); } else { _sendTimeout = TimeSpan.Zero; } _transport = new SocketTransportAdapter(nodeDefinition, groupDefinition, 1); }
private bool ContainsNode(RelayNodeDefinition nodeDefinition) { if (Me != null && Me.ToString() == nodeDefinition.ToString()) { return(true); } foreach (Node node in Nodes) { if (node.ToString() == nodeDefinition.ToString()) { return(true); } } return(false); }
public ushort GetLocalZone() { if (!lookedForZone) { lock (localZoneLock) { if (!lookedForZone) { RelayNodeDefinition myDefinition = GetMyNode(); if (myDefinition != null && myDefinition.Zone > 0) { localZone = myDefinition.Zone; log.InfoFormat("This server is using the zone override {0} as its local zone", localZone); } else { List <IPAddress> addresses; int portNumber; GetMyNetworkInfo(out addresses, out portNumber); localZone = 1; if (addresses != null) { localZone = FindLocalZone(addresses); if (localZone != 0) { log.InfoFormat("This server is using {0} as its local zone", localZone); } else { log.Warn("This server was not found in any defined zones and is defaulting to 0"); } } else { log.Warn("This server was not found in any defined zones and is defaulting to 0"); } } lookedForZone = true; } } } return(localZone); }
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 a new instance of the <see cref="RelayEndPoint"/> class, and presents a <see cref="IRelayMessageSender"/>. /// </summary> /// <param name="nodeDefinition">The node definition.</param> /// <param name="groupDefinition">The group definition.</param> /// <exception cref="InvalidOperationException">Thrown if the RelayNode configuration member "ServiceType" is set to an invalid value.</exception> /// <remarks>A RelayEndPoint references either a PipelineTransport or or SocketTransport type endpoint, which is configured in the RelayNodeMapping. /// A pipeline node will have the PipelinePort set to a nonzero value. A SocketTransport node will have the ServiceType="Sockets" and Port set /// to a nonzero value.</remarks> public RelayEndPoint(RelayNodeDefinition nodeDefinition, RelayNodeGroupDefinition groupDefinition) { var address = Dns.GetHostAddresses(nodeDefinition.Host)[0]; if (nodeDefinition.PipelinePort != 0) { _ipEndPoint = new IPEndPoint(address, nodeDefinition.PipelinePort); InstantiatePipelineClient(groupDefinition); } else { if (nodeDefinition.ServiceType == "Sockets") { _ipEndPoint = new IPEndPoint(address, nodeDefinition.Port); InstantiateSocketTransportClient(nodeDefinition, groupDefinition); } else { throw new InvalidOperationException(String.Format("An invalid ServiceType, {0}, was defined for Relay Node {2}/{1}.", nodeDefinition.ServiceType, nodeDefinition.Host, groupDefinition.Name)); } } }
/// <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++; } }
public void LoadSettings(RelayNodeDefinition node, RelayNodeGroupDefinition group) { MySpace.SocketTransport.SocketSettings newSettings = BuildSettings(group.SocketSettings); if (newSettings.SameAs(settings)) { return; } IDisposable disposableObject = null; try { settings = newSettings; socketClient = new SocketClient(node.IPEndPoint, settings); disposableObject = asyncSocketClient; asyncSocketClient = new AsyncSocketClient(node.IPEndPoint, new SocketPoolConfig { ReceiveTimeout = settings.ReceiveTimeout, NetworkOrdered = settings.UseNetworkOrder, ConnectTimeout = settings.ConnectTimeout, LoanCapacity = settings.PoolSize }); } finally { if (disposableObject != null) { try { asyncSocketClient.Dispose(); } catch (Exception ex) { log.Error("Failed to dispose AsyncSocketClient", ex); } } } }
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); }
/// <summary> /// this (or <see cref="ReloadConfig"/>) gets called (depending) when the TypeSettings.Config file /// are changed. /// </summary> /// <remarks> /// Added: craigbro /// cachedTypeSettings now held with the forwarder for reference of /// exceptions on Synchronous "in" messages. /// To reload, we just null out the cached TypeSettingsCollection object and the /// accessor will reload it on next call /// While ConfigurationManager.GetSection is quite performant after the 1st hit, /// keeping them cached is about twice as fast. /// </remarks> /// <param name="config"></param> /// <param name="runState"></param> private void LoadConfig(RelayNodeConfig config, ComponentRunState runState) { if (config != null) { if (config.RelayComponents != null) { object configObject = config.RelayComponents.GetConfigFor(GetComponentName()); ForwardingConfig forwardingConfig = configObject as ForwardingConfig; if(forwardingConfig == null) { if(_log.IsInfoEnabled) { _log.Info("No forwarding configuration supplied. Using defaults."); } forwardingConfig = new ForwardingConfig(); } NodeManager.Initialize(config, forwardingConfig, GetErrorQueues(runState)); _enableAsyncBulkGets = forwardingConfig.EnableAsyncBulkGets; _myNodeDefinition = NodeManager.Instance.GetMyNodeDefinition(); short maxTypeId = 0; if(config.TypeSettings != null) { maxTypeId = config.TypeSettings.MaxTypeId; } DebugWriter.SetTraceSettings(maxTypeId,forwardingConfig.TraceSettings); DebugWriter.WriteCallingMethod = forwardingConfig.WriteCallingMethod; DebugWriter.WriteMessageTrace = forwardingConfig.WriteMessageTrace; } else { NodeManager.Initialize(null, null, null); } } else { NodeManager.Initialize(null, null, null); } }
/// <summary> /// this (or <see cref="LoadConfig"/>) gets called (depending) when the TypeSettings.Config file /// are changed. /// </summary> /// <remarks> /// Added: craigbro /// cachedTypeSettings now held with the forwarder for reference of /// exceptions on Synchronous "in" messages. /// To reload, we just null out the cached TypeSettingsCollection object and the /// accessor will reload it on next call /// While ConfigurationManager.GetSection is quite performant after the 1st hit, /// keeping them cached is about twice as fast. /// </remarks> /// <param name="config">The config to reload</param> public void ReloadConfig(RelayNodeConfig config) { lock (_reloadLock) { if (config != null) { try { object configObject = config.RelayComponents.GetConfigFor(GetComponentName()); ForwardingConfig forwardingConfig = configObject as ForwardingConfig; if (forwardingConfig == null) { if(_log.IsInfoEnabled) { _log.InfoFormat("No forwarding configuration supplied. Reloading using defaults."); } forwardingConfig = new ForwardingConfig(); } NodeManager.Instance.ReloadConfig(config, forwardingConfig); _enableAsyncBulkGets = forwardingConfig.EnableAsyncBulkGets; _myNodeDefinition = NodeManager.Instance.GetMyNodeDefinition(); short maxTypeId = 0; if (config.TypeSettings != null) { maxTypeId = config.TypeSettings.MaxTypeId; } DebugWriter.SetTraceSettings(maxTypeId, forwardingConfig.TraceSettings); DebugWriter.WriteCallingMethod = forwardingConfig.WriteCallingMethod; DebugWriter.WriteMessageTrace = forwardingConfig.WriteMessageTrace; } catch (Exception ex) { if (_log.IsErrorEnabled) _log.ErrorFormat("Exception reloading config: {0}", ex); } } } }
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; } }
private bool ContainsNode(RelayNodeDefinition nodeDefinition) { if (Me != null && Me.ToString() == nodeDefinition.ToString()) { return true; } foreach (Node node in Nodes) { if (node.ToString() == nodeDefinition.ToString()) { return true; } } return false; }
internal static string GetMessageQueueNameFor(RelayNodeDefinition nodeDefinition) { return("Relay Node " + nodeDefinition); }
internal static string GetMessageQueueNameFor(RelayNodeDefinition nodeDefinition) { return "Relay Node " + nodeDefinition; }
internal void ReloadMapping(RelayNodeDefinition relayNodeDefinition, ForwardingConfig forwardingConfig) { NodeDefinition = relayNodeDefinition; Interlocked.Exchange(ref _messageBurstLength, forwardingConfig.MessageBurstLength); Interlocked.Exchange(ref _messageBurstTimeout, forwardingConfig.MessageBurstTimeout); _repostMessageLists = forwardingConfig.RepostMessageLists; if (EndPoint != null) { DetectedZone = NodeManager.Instance.GetZoneForAddress(EndPoint.Address); } else { DetectedZone = 0; } _messageBurstTimeoutSpan = TimeSpan.FromMilliseconds(_messageBurstTimeout); if (MessageErrorQueue == null) { MessageErrorQueue = new MessageQueue(NodeGroup.GetQueueConfig()); } else { MessageErrorQueue.ReloadConfig(NodeGroup.GetQueueConfig()); } SocketTransportAdapter socketTransport = _transport as SocketTransportAdapter; if (socketTransport != null) { socketTransport.LoadSettings(NodeDefinition, NodeGroup.GroupDefinition); } //changes in other forwarding settings are handled by the nodemanager using the Set & Start NewDispatcher methods. }
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; } }
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(); } }
private void InstantiateSocketTransportClient(RelayNodeDefinition nodeDefinition, RelayNodeGroupDefinition groupDefinition) { RelayMessageSender = new SocketTransportSender(nodeDefinition, groupDefinition); }
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; } } }
/// <summary> /// Initializes a new instance of the <see cref="ErrorQueue"/> class. /// </summary> /// <param name="config">The QueueConfig settings from RelayComponents.config.</param> /// <param name="nodeDefinition">The RelayNodeDefinition settings from RelayNodeMapping.config.</param> internal ErrorQueue(QueueConfig config, RelayNodeDefinition nodeDefinition) { _nodeName = string.Format("{0}-{1}", nodeDefinition.Host, nodeDefinition.Port); SetConfig(config); }