/// <summary> /// Stops the <see cref="RelayNode"/> server from accepting TCP/IP requests. /// </summary> public void Stop() { if (queuedMessageCounterTimer != null) { queuedMessageCounterTimer.Change(Timeout.Infinite, Timeout.Infinite); queuedMessageCounterTimer.Dispose(); } var timer = Interlocked.Exchange(ref resetConnectionRefusalTimer, null); if (timer != null) { timer.Change(Timeout.Infinite, Timeout.Infinite); timer.Dispose(); } if (RefuseOutOfClusterConnection) { RefuseOutOfClusterConnection = false; } if (log.IsInfoEnabled) { log.Info("Shutting down socket transport."); } SocketServerAdapter.Shutdown(); if (log.IsInfoEnabled) { log.Info("Disposing Dispatcher."); } inDispatcher.Dispose(); var od = outDispatcher; //in case of config reload to null if (od != null) { outDispatcher.Dispose(); } StopHttpServer(); components.Shutdown(); if (log.IsInfoEnabled) { log.Info("Resetting Counters"); } if (counters != null) { counters.ResetCounters(); counters.Shutdown(); counters = null; } if (log.IsInfoEnabled) { log.Info("Relay Node Stopped."); } }
/// <summary> /// Starts the <see cref="RelayNode"/> server to listen for incoming TCP/IP /// requests on the configured port. /// </summary> public void Start() { counters = new RelayNodeCounters(); countersInternal = new RelayNodeCounters(); countersInternal.Initialize("Internal"); counters.Initialize(instanceName); if (portNumber != 0) { var resetDuration = GetResetDuration(); bool whitelistOnly = resetDuration > 0; if (whitelistOnly && clusterAddresses == null) { throw new ApplicationException( "Cannot configure refuse out of cluster connections when node not in cluster."); } SocketServerAdapter.Initialize(instanceName, portNumber, this, configuration.OutMessagesOnRelayThreads, IsInCluster, whitelistOnly); if (whitelistOnly) { resetConnectionRefusalTimer = new Timer(state => { var timer = Interlocked.Exchange(ref resetConnectionRefusalTimer, null); if (timer != null) { RefuseOutOfClusterConnection = false; timer.Dispose(); } }, null, resetDuration * 1000, Timeout.Infinite); } else { resetConnectionRefusalTimer = null; } } StartHttpServer(); }
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"); } } }