/// <summary>
		/// Starts the server and loads the <see cref="IRelayNode"/> instance's assembly.
		/// </summary>
		/// <param name="runStates">State information to start the instance with.</param>
		/// <exception cref="Exception">Thrown when an error occurs, caller should call <see cref="Stop"/> in this cass.</exception>
		public void Start(ComponentRunState[] runStates)
		{
			bool setDllDirectorySuccess = SetDllDirectory(assemblyPath);

			if (setDllDirectorySuccess)
			{
				if (log.IsInfoEnabled)
					log.InfoFormat("Set DllDirectory to {0}. Unmanaged dlls will be imported from this folder.", assemblyPath);
			}
			else
			{
				if (log.IsErrorEnabled)
					log.ErrorFormat("Failed to set DllDirectory to {0}. Components that rely on unmanaged DLLs will not work.", assemblyPath);
			}

			if (log.IsInfoEnabled) 
				log.Info("Getting new node.");

			//enable this manually after the server is up an running because on server startup
			//code that modifies the directory will cause the domain to reload.
			AssemblyLoader.Instance.EnableRaisingEvents = false;
			relayNode = AssemblyLoader.Instance.GetRelayNode(nodeChangedDelegate);

			if (relayNode != null)
			{
				if (log.IsInfoEnabled)
				{
					log.Info("New node created.");
					log.Info("Initializing Relay Node Instance");
				}
				relayNode.Initialize(runStates);

				if (log.IsInfoEnabled)
					log.Info("Relay Node Initialized, Starting");
				relayNode.Start();
				if (log.IsInfoEnabled)
					log.Info("Relay Node Started");

				AssemblyLoader.Instance.EnableRaisingEvents = true;
			}
			else
			{
				if (log.IsErrorEnabled)
					log.Error("Error starting Relay Server: No Relay Node implemenation found!");
			}
		}
Example #2
0
		/// <summary>
		/// Initializes the <see cref="RelayNode"/> with the given <see cref="ComponentRunState"/>s,
		/// must be called before calling <see cref="Start"/>
		/// </summary>
		/// <param name="componentRunStates"></param>
		public void Initialize(ComponentRunState[] componentRunStates)
		{
			try
			{
                if (log.IsInfoEnabled)
                {
                    if (componentRunStates == null)
                    {
                        log.Info("Initializing Relay Node.");
                    }
                    else
                    {
                        log.Info("Initialzing Relay Node with Component Run States.");
                    }
                }

				EnvironmentManager.EnvironmentChanged += EnvironmentChangedHandler;

                GetConfig();
				
				if (configuration == null) throw new ConfigurationErrorsException("config failed to load, is null");

				SetClusterAddresses(configuration);

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

				components = new RelayComponents(configuration);

				if (configuration != null)
				{
					messageTracer = new MessageTracer(configuration.TypeSettings.MaxTypeId, configuration.TraceSettings);
					messageTracer.Activated = configuration.OutputTraceInfo;

					const string inThreadsName = "DataRelayNode";
					if (configuration.NumberOfThreads > 0)
					{
						inDispatcher = new Dispatcher(configuration.NumberOfThreads, ThreadPriority.Normal, true, inThreadsName);
					}
					else
					{
						inDispatcher = new Dispatcher() { Name = inThreadsName } ;
					}

					const string outThreadsName = "DataRelayNodeOUT";
					if (configuration.OutMessagesOnRelayThreads)
					{
						if (configuration.NumberOfOutMessageThreads > 0)
						{
							outDispatcher = new Dispatcher(configuration.NumberOfOutMessageThreads, ThreadPriority.Normal, true, outThreadsName);
						}
						else
						{
							outDispatcher = new Dispatcher { Name = outThreadsName };
						}

						outMessagePort = new Port<RelayMessageAsyncResult>();
						outMessagesPort = new Port<RelayMessageListAsyncResult>();

						outMessageQueue = new DispatcherQueue("DataRelayDispatcherQueueOUT", outDispatcher, TaskExecutionPolicy.ConstrainQueueDepthThrottleExecution, configuration.MaximumOutMessageQueueDepth);
						Arbiter.Activate(outMessageQueue,
								Arbiter.ReceiveWithIterator(true, outMessagePort, HandleOutMessage));
						Arbiter.Activate(outMessageQueue,
								Arbiter.ReceiveWithIterator(true, outMessagesPort, HandleOutMessages));
					}

					inMessageQueue = new DispatcherQueue("DataRelayDispatcherQueue", inDispatcher, TaskExecutionPolicy.ConstrainQueueDepthThrottleExecution, configuration.MaximumMessageQueueDepth);
					
					queuedTaskThreshold = (int)Math.Floor(0.9 * configuration.MaximumMessageQueueDepth);
					
					
					// setup RelayServicesClient before initalizing components
					RelayServicesClient.Instance.RelayNodeServices = this;
					
					Arbiter.Activate(inMessageQueue,
						Arbiter.Receive<RelayMessage>(true, inMessagePort, HandleInMessage));
					Arbiter.Activate(inMessageQueue,
								Arbiter.Receive<RelayMessageWithContext>(true, inMessageWithContextPort, HandleInMessage));
					Arbiter.Activate(inMessageQueue,
								Arbiter.Receive<IList<RelayMessage>>(true, inMessagesPort, HandleInMessages));
					

					//by having after the Arbiter.Activate it allows Initialize components to use 
					//IRelayNodeServices that require Message handling
					components.Initialize(componentRunStates, configuration.IgnoredMessageTypes);

					queuedMessageCounterTimer = new Timer(CountQueuedMessages, null, 5000, 5000);
				}
			}
			catch (Exception ex)
			{
                if (log.IsErrorEnabled)
                    log.ErrorFormat("Exception initializing relay node: {0}", ex);
				throw; //should bring server down
			}
		}