IAsyncResult IAsyncRelayTransport.BeginSendMessage(SerializedRelayMessage message, AsyncCallback callback, object state)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            if (message.IsTwoWayMessage)
            {
                throw new ApplicationException("Cannot send pre-serialized out message.");
            }

            var result = new SimpleAsyncResult(callback, state);

            asyncSocketClient.SendOneWayAsync <MemoryStream>(
                (short)SocketCommand.HandleOneWayMessage,
                message.MessageStream,
                (messageStream, stream) => stream.Write(
                    messageStream.GetBuffer(),
                    (int)messageStream.Position,
                    (int)messageStream.Length),
                args =>
            {
                result.Error = args.Error;
                result.CompleteOperation(args.CompletedSynchronously);
            });
            return(result);
        }
Example #2
0
 /// <summary>
 /// Calls the NotifyDroppedMessage event with the supplied message.
 /// </summary>
 public static void RaiseMessageDropped(SerializedRelayMessage message)
 {
     if (MessageDropped != null)
     {
         MessageDropped(message);
     }
 }
Example #3
0
		/// <summary>
		/// Enqueues a single message to the error queue.
		/// </summary>
		/// <remarks>
		/// Two-way messages are ignored.
		/// </remarks>
		/// <param name="message">The message.</param>
		internal void Enqueue(SerializedRelayMessage message)
		{
			if (message.IsTwoWayMessage)
				return;

			SerializedRelayMessage discard = null;

			if (_enabled)
			{
				lock (_inMessageQueueLock)
				{
					NodeManager.Instance.Counters.IncrementErrorQueue();
					InMessageQueue.Enqueue(message);

					if (_persistence == null && InMessageQueue.Count > _maxCount)
					{
						discard = InMessageQueue.Dequeue();
					}
				}

				if (discard != null)
				{
					Forwarder.RaiseMessageDropped(discard);
					NodeManager.Instance.Counters.DecrementErrorQueue();
					IncrementDiscardsBy(1);
				}

				StartSpill();
			}
			else
			{
				Forwarder.RaiseMessageDropped(message);
			}
		}
Example #4
0
 void IRelayTransport.SendMessage(SerializedRelayMessage serializedMessage)
 {
     if (DoDispatchMessages)
     {
         RelayMessage message = RelayMessageFormatter.ReadRelayMessage(serializedMessage.MessageStream);
         _messageRecieved(message);
     }
 }
Example #5
0
 /// <summary>
 /// Calls the NotifyDroppedMessage event with the supplied message.
 /// </summary>
 public static void RaiseMessageDropped(RelayMessage message)
 {
     if (MessageDropped != null)
     {
         SerializedRelayMessage serializedMessage = new SerializedRelayMessage(message);
         MessageDropped(serializedMessage);
     }
 }
Example #6
0
        private void CalculateLife(SerializedRelayMessage message)
        {
            if (_avgMessageLife == null)
            {
                return;
            }

            _avgMessageLife.CalculateLife(message);
        }
        public void SendMessage(SerializedRelayMessage message)
        {
            if (message.IsTwoWayMessage)
            {
                throw new ApplicationException("Cannot send pre-serialized out message.");
            }

            socketClient.SendOneWay((int)SocketCommand.HandleOneWayMessage, message.MessageStream);
        }
Example #8
0
		/// <summary>
		/// Enqueues a list of messages to the error queue.
		/// </summary>
		/// <remarks>
		/// Two-way messages in the message list are ignored.
		/// </remarks>
		/// <param name="messages">The list of messages.</param>
		internal void Enqueue(IList<SerializedRelayMessage> messages)
		{
			if (_enabled && messages.Count > 0)
			{
				int count = 0;
				SerializedRelayMessage[] discards = null;

				lock (_inMessageQueueLock)
				{
					for (int i = 0; i < messages.Count; ++i)
					{
						var message = messages[i];
						if (!message.IsTwoWayMessage)
						{
							InMessageQueue.Enqueue(message);
							++count;
						}
					}

					if (_persistence == null && InMessageQueue.Count > _maxCount)
					{
						discards = new SerializedRelayMessage[InMessageQueue.Count - _maxCount];
						for (int i = 0; i < discards.Length; ++i)
						{
							discards[i] = InMessageQueue.Dequeue();
						}
					}
				}

				if (discards != null)
				{
					for (int i = 0; i < discards.Length; ++i)
					{
						Forwarder.RaiseMessageDropped(discards[i]);
					}
					NodeManager.Instance.Counters.DecrementErrorQueueBy(discards.Length);
					IncrementDiscardsBy(discards.Length);
				}

				if (count > 0)
				{
					NodeManager.Instance.Counters.IncrementErrorQueueBy(count);
					StartSpill();
				}
			}
			else
			{
				for (int i = 0; i < messages.Count; i++)
				{
					var message = messages[i];
					if (!message.IsTwoWayMessage)
						Forwarder.RaiseMessageDropped(message);
				}
			}
		}
Example #9
0
        IAsyncResult IAsyncRelayTransport.BeginSendMessage(SerializedRelayMessage message, AsyncCallback callback, object state)
        {
            var result = new SimpleAsyncResult(callback, state);

            ThreadPool.QueueUserWorkItem(o =>
            {
                ((IRelayTransport)this).SendMessage(message);
                result.SetComplete();
            });
            return(result);
        }
Example #10
0
 internal static void LogNodeException(SerializedRelayMessage message, Node node, Exception ex)
 {
     if (_log.IsErrorEnabled)
     {
         if (ex is SocketException)
         {
             SocketException sex = (SocketException)ex;
             _log.ErrorFormat("Socket error {0} while handling {1} for node {2}", sex.SocketErrorCode, message, node.ToExtendedString());
         }
         else
         {
             _log.ErrorFormat("Error handling {0} for node {1}: {2}", message, node, ex);
         }
     }
 }
Example #11
0
        internal void CountMessage(SerializedRelayMessage message)
        {
            if (_countersInitialized)
            {
                CalculateLife(message);

                if (message.IsTwoWayMessage)
                {
                    CountOutMessage(message.MessageType, message.PayloadLength);
                }
                else
                {
                    CountInMessage(message.MessageType, message.PayloadLength);
                }
            }
        }
		internal void Enqueue(SerializedRelayMessage message)
		{
			if (_enabled)
			{
				if (message.IsTwoWayMessage)
				{
					return;
				}
				lock (_inMessageQueueLock)
				{
					while (InMessageQueue.Count >= (_maxCount - 1))
					{
						Forwarder.RaiseMessageDropped(InMessageQueue.Dequeue());
						NodeManager.Instance.Counters.DecrementErrorQueue();
					}
					NodeManager.Instance.Counters.IncrementErrorQueue();
					InMessageQueue.Enqueue(message);
				}
			}
			else
			{
				Forwarder.RaiseMessageDropped(message);
			}
		}
 internal void Enqueue(SerializedRelayMessage message)
 {
     if (_enabled)
     {
         if (message.IsTwoWayMessage)
         {
             return;
         }
         lock (_inMessageQueueLock)
         {
             while (InMessageQueue.Count >= (_maxCount - 1))
             {
                 Forwarder.RaiseMessageDropped(InMessageQueue.Dequeue());
                 NodeManager.Instance.Counters.DecrementErrorQueue();
             }
             NodeManager.Instance.Counters.IncrementErrorQueue();
             InMessageQueue.Enqueue(message);
         }
     }
     else
     {
         Forwarder.RaiseMessageDropped(message);
     }
 }
Example #14
0
        /// <summary>
        ///	Performs processing on single message
        /// </summary>
        /// <exception cref="SyncRelayOperationException">
        /// When the type of an object is defined with settings
        ///		<see cref="MySpace.DataRelay.Common.Schemas.TypeSettings"></see> with
        ///		SyncInMessages=true and
        ///		ThrowOnSyncFailure=true
        ///	failed "in" executions will throw this exception
        /// </exception>
        /// <param name="message">Message to be processed</param>
        public void HandleMessage(RelayMessage message)
        {
            Node node;

            if (message.IsTwoWayMessage)
            {
                int  allowedRetries = NodeManager.Instance.GetRetryCountForMessage(message);
                bool triedBefore    = false;
                do
                {
                    if (PrepareMessage(message, triedBefore).Pop(out node))
                    {
                        triedBefore = true;
                        node.HandleOutMessage(message);
                    }
                    else
                    {
                        message.SetError(RelayErrorType.NoNodesAvailable);
                    }
                }while (message.ErrorType == RelayErrorType.NodeUnreachable && --allowedRetries >= 0);
            }
            else
            {
                SimpleLinkedList <Node> nodes                      = PrepareMessage(message, false);
                SerializedRelayMessage  serializedMessage          = new SerializedRelayMessage(message);
                SerializedRelayMessage  serializedMessageInterZone = null;

                bool messageHandled = true;                 // start with "true" so that we do not pop
                // if there are no items in "nodes"
                if (nodes.Count == 0)
                {
                    message.SetError(RelayErrorType.NoNodesAvailable);
                }
                else
                {
                    while (nodes.Pop(out node))
                    {
                        TypeSetting typeSetting = NodeManager.Instance.Config.TypeSettings.TypeSettingCollection[message.TypeId];

                        bool typesettingThrowOnSyncFailure = false;
                        bool typesettingSyncInMessages     = false;
                        if (null != typeSetting && !node.NodeCluster.MeInThisCluster)
                        {
                            typesettingSyncInMessages     = typeSetting.SyncInMessages;
                            typesettingThrowOnSyncFailure = typeSetting.ThrowOnSyncFailure;
                        }

                        if (_myNodeDefinition != null && _myNodeDefinition.Zone != node.NodeDefinition.Zone)
                        {
                            // Message needs to cross Zone bounderies
                            if (serializedMessageInterZone == null)
                            {
                                serializedMessageInterZone = new SerializedRelayMessage(RelayMessage.CreateInterZoneMessageFrom(message));
                            }

                            if (message.ResultOutcome == null)
                            {
                                message.ResultOutcome = RelayOutcome.Queued;
                            }
                            node.HandleInMessage(serializedMessageInterZone);
                        }
                        else if (typesettingSyncInMessages)
                        {
                            messageHandled = node.HandleInMessageSync(message, typesettingSyncInMessages, typesettingThrowOnSyncFailure);
                        }
                        else
                        {
                            if (message.ResultOutcome == null)
                            {
                                message.ResultOutcome = RelayOutcome.Queued;
                            }
                            node.HandleInMessage(serializedMessage);
                        }

                        if (!messageHandled)
                        {
                            throw new SyncRelayOperationException(string.Format("Node {0} failed to process message {1}\r\n", node, message));
                        }
                    }
                }
            }
        }
Example #15
0
		/// <summary>
		/// Calls the NotifyDroppedMessage event with the supplied message.
		/// </summary>    
		public static void RaiseMessageDropped(SerializedRelayMessage message)
		{
			if (MessageDropped != null)
			{
				MessageDropped(message);
			}
		}
Example #16
0
		/// <summary>
		/// Calls the NotifyDroppedMessage event with the supplied message.
		/// </summary>        
		public static void RaiseMessageDropped(RelayMessage message)
		{
			if (MessageDropped != null)
			{
				SerializedRelayMessage serializedMessage = new SerializedRelayMessage(message);
				MessageDropped(serializedMessage);
			}
		}
		internal void CountInMessages(SerializedRelayMessage[] messages)
		{
			if (_countersInitialized)
			{
				SerializedRelayMessage msg;
				for (int i = 0; i < messages.Length; i++)
				{
					msg = messages[i];
					CalculateLife(msg);
					CountInMessage(msg.MessageType, msg.PayloadLength);
				}
			}
		}
Example #18
0
		/// <summary>
		///	Performs processing on single message
		/// </summary>
		/// <exception cref="SyncRelayOperationException">
		/// When the type of an object is defined with settings
		///		<see cref="MySpace.DataRelay.Common.Schemas.TypeSettings"></see> with 
		///		SyncInMessages=true and 
		///		ThrowOnSyncFailure=true
		///	failed "in" executions will throw this exception
		/// </exception>
		/// <param name="message">Message to be processed</param>
		public void HandleMessage(RelayMessage message)
		{
			
			Node node;
			if (message.IsTwoWayMessage)
			{
				int allowedRetries = NodeManager.Instance.GetRetryCountForMessage(message);
				bool triedBefore = false;
				do
				{
					if (PrepareMessage(message, triedBefore).Pop(out node))
					{
						triedBefore = true;
						node.HandleOutMessage(message);
					}
					else
					{
						message.SetError(RelayErrorType.NoNodesAvailable);
					}
				}
				while (message.ErrorType == RelayErrorType.NodeUnreachable && --allowedRetries >= 0);
			}
			else
			{
				SimpleLinkedList<Node> nodes = PrepareMessage(message, false);
				SerializedRelayMessage serializedMessage = new SerializedRelayMessage(message);
				SerializedRelayMessage serializedMessageInterZone = null;

				bool messageHandled = true; // start with "true" so that we do not pop
				// if there are no items in "nodes"
				if (nodes.Count == 0)
				{
					message.SetError(RelayErrorType.NoNodesAvailable);
				}
				else
				{
					while (nodes.Pop(out node))
					{
						TypeSetting typeSetting = NodeManager.Instance.Config.TypeSettings.TypeSettingCollection[message.TypeId];

						bool typesettingThrowOnSyncFailure = false;
						bool typesettingSyncInMessages = false;
						if (null != typeSetting && !node.NodeCluster.MeInThisCluster)
						{
							typesettingSyncInMessages = typeSetting.SyncInMessages;
							typesettingThrowOnSyncFailure = typeSetting.ThrowOnSyncFailure;
						}

						if (_myNodeDefinition != null && _myNodeDefinition.Zone != node.NodeDefinition.Zone)
						{
							// Message needs to cross Zone bounderies
							if (serializedMessageInterZone == null)
							{
								serializedMessageInterZone = new SerializedRelayMessage(RelayMessage.CreateInterZoneMessageFrom(message));
							}

							if (message.ResultOutcome == null) message.ResultOutcome = RelayOutcome.Queued;
							node.HandleInMessage(serializedMessageInterZone);
						}
						else if (typesettingSyncInMessages)
						{
							messageHandled = node.HandleInMessageSync(message, typesettingSyncInMessages, typesettingThrowOnSyncFailure);
						}
						else
						{
							if (message.ResultOutcome == null) message.ResultOutcome = RelayOutcome.Queued;
							node.HandleInMessage(serializedMessage);
						}

						if (!messageHandled)
						{
							throw new SyncRelayOperationException(string.Format("Node {0} failed to process message {1}\r\n", node, message));
						}
					}
				}
			}
		}
		private void CalculateLife(SerializedRelayMessage message)
		{
			if (_avgMessageLife == null) 
				return;
			
			_avgMessageLife.CalculateLife(message);
		}
		internal void CountMessage(SerializedRelayMessage message)
		{
			if (_countersInitialized)
			{
				CalculateLife(message);

				if (message.IsTwoWayMessage)
				{
					CountOutMessage(message.MessageType, message.PayloadLength);
				}
				else
				{
					CountInMessage(message.MessageType, message.PayloadLength);
				}
			}
		}
		IAsyncResult IAsyncRelayTransport.BeginSendMessage(SerializedRelayMessage message, AsyncCallback callback, object state)
		{
			if (message == null) throw new ArgumentNullException("message");

			if (message.IsTwoWayMessage)
			{
				throw new ApplicationException("Cannot send pre-serialized out message.");
			}

			var result = new SimpleAsyncResult(callback, state);
			asyncSocketClient.SendOneWayAsync<MemoryStream>(
				(short)SocketCommand.HandleOneWayMessage,
				message.MessageStream,
				(messageStream, stream) => stream.Write(
					messageStream.GetBuffer(),
					(int)messageStream.Position,
					(int)messageStream.Length),
					args =>
					{
						result.Error = args.Error;
						result.CompleteOperation(args.CompletedSynchronously);
					});
			return result;
		}
		IAsyncResult IAsyncRelayTransport.BeginSendInMessageList(SerializedRelayMessage[] messages, AsyncCallback callback, object state)
		{
			throw new NotSupportedException();
		}
Example #23
0
		private void CaculateStatisics(SerializedRelayMessage message, long milliseconds)
		{
			int index = (int)message.MessageType;
			Interlocked.Increment(ref _messageCounts[index]);
			Interlocked.Exchange(ref _lastMessageTimes[index], milliseconds);
			Interlocked.Exchange(ref _averageMessageTimes[index], CalculateAverage(_averageMessageTimes[index], milliseconds, _messageCounts[index]));
		}
Example #24
0
		/// <summary>
		/// Processes a single message
		/// Calls DoHandleMessage if the message is to be processed synchronously
		/// Posts message to process queue otherwise
		/// </summary>
		/// <param name="message">Message to be processed</param>
		/// <param name="useSyncForInMessages">Default: false
		/// The type (from TypeSettings.config) can require synchronous handling for messages
		/// </param>
		/// <param name="skipErrorQueueForSync">Default: false
		/// The type (from TypeSettings.config) can require that should the message processing fail,
		/// the message will NOT be sent to the Error Queue for retry.  Instead, the function returns
		/// false.
		/// Has no effect if useSyncForInMessages is false.
		/// </param>
		/// <returns>
		/// useSyncForInMessages = false	always returns True (message processed Async)
		/// useSyncForInMessages = true, skipErrorQueueForSync = false	always returns True (errors placed in queue for retry)
		/// useSyncForInMessages = true, skipErrorQueueForSync = true	returns true if the message processing succeeded
		/// </returns>
		internal bool HandleInMessageSync(RelayMessage message, bool useSyncForInMessages, bool skipErrorQueueForSync)
		{
			if (useSyncForInMessages)
			{
				return DoHandleMessage(message, useSyncForInMessages, skipErrorQueueForSync);
			}

			message.ResultOutcome = RelayOutcome.Queued;
			SerializedRelayMessage serializedMessage = new SerializedRelayMessage(message);
			_serializedMessagePort.Post(serializedMessage);

			return true;
		}
Example #25
0
		private void CaculateInStatisics(SerializedRelayMessage[] messages, long milliseconds)
		{
			Interlocked.Increment(ref _bulkInMessageCount);
			Interlocked.Exchange(ref _lastBulkInMessageLength, messages.Length);
			Interlocked.Exchange(ref _averageBulkInMessageLength, CalculateAverage(_averageBulkInMessageLength, _lastBulkInMessageLength, _bulkInMessageCount));
			Interlocked.Exchange(ref _lastBulkInMessageTime, milliseconds);
			Interlocked.Exchange(ref _averageBulkInMessageTime, CalculateAverage(_averageBulkInMessageTime, _lastBulkInMessageTime, _bulkInMessageCount));
		}
Example #26
0
 void IRelayTransport.SendMessage(SerializedRelayMessage message)
 {
     DoAllTransports(t => t.SendMessage(message));
 }
Example #27
0
		internal void HandleInMessage(SerializedRelayMessage serializedRelayMessage)
		{
			_serializedMessagePort.Post(serializedRelayMessage);
		}
Example #28
0
		private void EnqueueMessage(SerializedRelayMessage message)
		{
			if (MessageErrorQueue != null)
			{
				MessageErrorQueue.Enqueue(message);
			}
			else
			{
				Forwarder.RaiseMessageDropped(message);
			}
		}
Example #29
0
		private void EnqueueInMessages(SerializedRelayMessage[] messages)
		{
			if (MessageErrorQueue != null)
			{
				MessageErrorQueue.Enqueue(messages);
			}
			else
			{
				for (int i = 0; i < messages.Length; i++)
				{
					Forwarder.RaiseMessageDropped(messages[i]);
				}
			}
		}
Example #30
0
		private void DoHandleMessage(SerializedRelayMessage message)
		{
			if (!Activated || message == null || message.MessageStream == null)
			{
				return;
			}

			if (DangerZone)
			{
				EnqueueMessage(message);
				return;
			}

			try
			{
				if (GatherStats)
				{
					Stopwatch watch = Stopwatch.StartNew();

					_transport.SendMessage(message);
					watch.Stop();
					CaculateStatisics(message, watch.ElapsedMilliseconds);
				}
				else
				{
					_transport.SendMessage(message);
				}
				NodeManager.Instance.Counters.CountMessage(message);
			}
			catch (Exception ex)
			{

				EnqueueMessage(message);
				InstrumentException(ex);
				NodeGroup.LogNodeException(message, this, ex);
			}
		}
Example #31
0
		/// <summary>
		/// Processes an array of RelayMessages
		/// </summary>
		/// <param name="messages">Array of messages to be processed</param>
		/// <param name="skipErrorQueueForSync">True if synchronous messages that fail should not be 
		/// placed into the error queue for retry.
		/// </param>
		/// <returns>
		/// skipErrorQueueForSync = false	always returns True (message processed Async)
		/// skipErrorQueueForSync = true	returns true if the message processing succeeded
		/// </returns>
		internal bool DoHandleInMessages(SerializedRelayMessage[] messages, bool skipErrorQueueForSync)
		{
			if (!Activated)
			{
				return false;
			}
			if (DangerZone)
			{
				if (skipErrorQueueForSync)
				{
					return false;
				}
				EnqueueInMessages(messages);
				return true;
			}

			bool messagesHandled = true;

			try
			{
				if (GatherStats)
				{
					Stopwatch watch = Stopwatch.StartNew();
					_transport.SendInMessageList(messages);
					watch.Stop();
					CaculateInStatisics(messages, watch.ElapsedMilliseconds);
				}
				else
				{
					_transport.SendInMessageList(messages);
				}
				NodeManager.Instance.Counters.CountInMessages(messages);
			}
			catch (Exception ex)
			{
				if (!skipErrorQueueForSync)
				{
					EnqueueInMessages(messages);
				}
				else
				{
					messagesHandled = false;
				}
				InstrumentException(ex);
				NodeGroup.LogNodeInMessageException(messages, this, ex);
			}

			return messagesHandled;
		}
Example #32
0
		internal static void LogNodeInMessageException(SerializedRelayMessage[] messages, Node node, Exception ex)
		{
			if (_log.IsErrorEnabled)
			{
				if (ex is SocketException)
				{
					SocketException sex = (SocketException)ex;
					_log.ErrorFormat("Socket error {0} while handling {1} IN messages for node {2}", sex.SocketErrorCode, messages.Length, node.ToExtendedString());
				}
				else
				{
					_log.ErrorFormat("Error handling {0} IN messages for node {1}: {2}.", messages.Length, node.ToExtendedString(), ex);
				}
			}
		}
		public void SendMessage(SerializedRelayMessage message)
		{
			if (message.IsTwoWayMessage)
			{
				throw new ApplicationException("Cannot send pre-serialized out message.");
			}

			socketClient.SendOneWay((int)SocketCommand.HandleOneWayMessage, message.MessageStream);
		}
		public void SendInMessageList(SerializedRelayMessage[] messages)
		{
			ResourcePoolItem<MemoryStream> pooledBuffer;
			MemoryStream nextMessageChunk;
			int chunkLength = defaultChunkLength;
			int cursor = 0;
			if (messages.Length > 0)
			{
				if (chunkLength == 0 || chunkLength > messages.Length)
				{
					//0 means "don't chunk"
					chunkLength = messages.Length;
				}

				pooledBuffer = bufferPool.GetItem();
				try
				{
					nextMessageChunk = pooledBuffer.Item;
					byte[] lengthBytes = BitConverter.GetBytes(chunkLength);
					while (cursor < messages.Length)
					{
						//make sure that the next chunk doesn't go past the end of the list
						if ((cursor + chunkLength) > messages.Length)
						{
							chunkLength = messages.Length - cursor;
							BitConverterEx.WriteBytes(lengthBytes, 0, chunkLength);
						}

						nextMessageChunk.Write(lengthBytes, 0, 4);

						for (int end = cursor + chunkLength; cursor < end; cursor++)
						{
							messages[cursor].MessageStream.WriteTo(nextMessageChunk);
						}

						socketClient.SendOneWay((int)SocketCommand.HandleOneWayMessages, nextMessageChunk);
						nextMessageChunk.Seek(0, SeekOrigin.Begin);
						nextMessageChunk.SetLength(0);
					}
				}
				finally
				{
					bufferPool.ReleaseItem(pooledBuffer);
				}
			}
		}
Example #35
0
 public void SendMessage(SerializedRelayMessage message)
 {
 }