internal MessagesWithLock(List<RelayMessage> messages, HandleWithCount locker)
		{
			Messages = messages;
			Locker = locker;
		}
示例#2
0
        /// <summary>
        ///	Performs processing on a block of messages
        /// </summary>
        /// <param name="messages">A list of RealyMessage objects to be processed</param>
        /// <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 executions will throw this exception
        /// </exception>
        /// <remarks>
        /// Procssing steps:
        ///	1. Splits the list of messages into several lists, each containing
        ///	the node, messages of a single type and settings for that type
        ///	2. Processes each list individually
        ///	3. Tracks the success/failure of each list
        ///	4. If a list (or a message from a list) fails, and the type of message
        ///	requires a "Throw" when sync fails: throws a SyncRelayOperationException,
        ///	otherwise, places failed messages into the exception queue
        /// </remarks>
        public void HandleMessages(IList <RelayMessage> messages)
        {
            SetHydrationPolicy(messages);
            NodeManager.Instance.Counters.CountMessageList(messages);
            NodeWithMessagesCollection distributedMessages = NodeManager.Instance.DistributeMessages(messages);
            NodeWithMessages           nodeMessages;
            AutoResetEvent             resetEvent   = null;
            HandleWithCount            finishedLock = null;

            List <NodeWithMessages> unhandledNodes = new List <NodeWithMessages>();

            if (_enableAsyncBulkGets && distributedMessages.Count > 1)             //only do the async if there's more than 1 node to send to. No point in hitting a wait handle if we don't need to coordinate a response
            {
                int numberOfGets = 0, getsLefts = 0;
                for (int i = 0; i < distributedMessages.Count; i++)
                {
                    if (distributedMessages[i].Messages.OutMessageCount > 0)
                    {
                        numberOfGets++;
                    }
                }
                if (numberOfGets > 0)
                {
                    resetEvent   = OutMessageWaitHandle;
                    finishedLock = new HandleWithCount(resetEvent, numberOfGets);
                    getsLefts    = numberOfGets;                  //use this to determine when we're at the last get so we use this thread to process it
                }

                for (int i = 0; i < distributedMessages.Count; i++)
                {
                    nodeMessages = distributedMessages[i];
                    if (nodeMessages.Messages.InMessageCount > 0)
                    {
                        bool inMessagesHandled = nodeMessages.NodeWithInfo.Node.HandleInMessages(nodeMessages.Messages.InMessages,
                                                                                                 nodeMessages.NodeWithInfo.SyncInMessages, nodeMessages.NodeWithInfo.SkipErrorQueueForSync);
                        if (!inMessagesHandled)
                        {
                            unhandledNodes.Add(nodeMessages);
                        }
                    }
                    if (nodeMessages.Messages.OutMessageCount > 0)
                    {
                        if (--getsLefts > 0)
                        {
                            nodeMessages.NodeWithInfo.Node.PostOutMessages(
                                new MessagesWithLock(nodeMessages.Messages.OutMessages, finishedLock));
                        }
                        else
                        {
                            nodeMessages.NodeWithInfo.Node.HandleOutMessages(nodeMessages.Messages.OutMessages);
                            finishedLock.Decrement();
                        }
                    }
                }
                if (numberOfGets > 0)
                {
                    resetEvent.WaitOne();
                }
                return;
            }
            else
            {
                for (int i = 0; i < distributedMessages.Count; i++)
                {
                    nodeMessages = distributedMessages[i];
                    if (nodeMessages.Messages.InMessageCount > 0)
                    {
                        bool inMessagesHandled = nodeMessages.NodeWithInfo.Node.HandleInMessages(nodeMessages.Messages.InMessages, nodeMessages.NodeWithInfo.SyncInMessages, nodeMessages.NodeWithInfo.SkipErrorQueueForSync);
                        if (!inMessagesHandled)
                        {
                            unhandledNodes.Add(nodeMessages);
                        }
                    }
                    if (nodeMessages.Messages.OutMessageCount > 0)
                    {
                        nodeMessages.NodeWithInfo.Node.HandleOutMessages(nodeMessages.Messages.OutMessages);
                    }
                }
            }

            if (unhandledNodes.Count > 0)
            {
                bool          bThrow        = false;
                StringBuilder detailBuilder = new StringBuilder();
                detailBuilder.Append("Error handling sync in messages\r\n");
                foreach (NodeWithMessages nwm in unhandledNodes)
                {
                    if (nwm.NodeWithInfo.SkipErrorQueueForSync && nwm.NodeWithInfo.SyncInMessages)
                    {
                        detailBuilder.AppendFormat("Node:{0}\r\n", nwm.NodeWithInfo.Node.GetType().Name);
                        detailBuilder.AppendFormat("\tMessages: {0}\r\n", nwm.Messages.InMessageCount);
                        bThrow = true;
                    }
                }
                if (bThrow)
                {
                    throw new SyncRelayOperationException(detailBuilder.ToString());
                }


                if (_log.IsInfoEnabled)
                {
                    _log.Info(detailBuilder.ToString());
                }
            }
        }
示例#3
0
 internal MessagesWithLock(List <RelayMessage> messages, HandleWithCount locker)
 {
     Messages = messages;
     Locker   = locker;
 }
示例#4
0
		/// <summary>
		///	Performs processing on a block of messages
		/// </summary>
		/// <param name="messages">A list of RealyMessage objects to be processed</param>
		/// <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 executions will throw this exception
		/// </exception>
		/// <remarks>
		/// Procssing steps:
		///	1. Splits the list of messages into several lists, each containing
		///	the node, messages of a single type and settings for that type
		///	2. Processes each list individually
		///	3. Tracks the success/failure of each list
		///	4. If a list (or a message from a list) fails, and the type of message
		///	requires a "Throw" when sync fails: throws a SyncRelayOperationException, 
		///	otherwise, places failed messages into the exception queue
		/// </remarks>
		public void HandleMessages(IList<RelayMessage> messages)
		{
			SetHydrationPolicy(messages);
			NodeManager.Instance.Counters.CountMessageList(messages);
			NodeWithMessagesCollection distributedMessages = NodeManager.Instance.DistributeMessages(messages);
			NodeWithMessages nodeMessages;
			AutoResetEvent resetEvent = null;
			HandleWithCount finishedLock = null;

			List<NodeWithMessages> unhandledNodes = new List<NodeWithMessages>();

			if (_enableAsyncBulkGets && distributedMessages.Count > 1) //only do the async if there's more than 1 node to send to. No point in hitting a wait handle if we don't need to coordinate a response
			{
				int numberOfGets = 0, getsLefts = 0;
				for (int i = 0; i < distributedMessages.Count; i++)
				{
					if (distributedMessages[i].Messages.OutMessageCount > 0)
					{
						numberOfGets++;
					}
				}
				if (numberOfGets > 0)
				{
					resetEvent = OutMessageWaitHandle;
					finishedLock = new HandleWithCount(resetEvent, numberOfGets);
					getsLefts = numberOfGets; //use this to determine when we're at the last get so we use this thread to process it
				}

				for (int i = 0; i < distributedMessages.Count; i++)
				{
					nodeMessages = distributedMessages[i];
					if (nodeMessages.Messages.InMessageCount > 0)
					{
						bool inMessagesHandled = nodeMessages.NodeWithInfo.Node.HandleInMessages(nodeMessages.Messages.InMessages,
							nodeMessages.NodeWithInfo.SyncInMessages, nodeMessages.NodeWithInfo.SkipErrorQueueForSync);
						if (!inMessagesHandled)
						{
							unhandledNodes.Add(nodeMessages);
						}
					}
					if (nodeMessages.Messages.OutMessageCount > 0)
					{
						if (--getsLefts > 0)
						{
							nodeMessages.NodeWithInfo.Node.PostOutMessages(
										  new MessagesWithLock(nodeMessages.Messages.OutMessages, finishedLock));
						}
						else
						{
							nodeMessages.NodeWithInfo.Node.HandleOutMessages(nodeMessages.Messages.OutMessages);
							finishedLock.Decrement();
						}
					}
				}
				if (numberOfGets > 0)
				{
					resetEvent.WaitOne();
				}
				return;
			}
			else
			{
				for (int i = 0; i < distributedMessages.Count; i++)
				{
					nodeMessages = distributedMessages[i];
					if (nodeMessages.Messages.InMessageCount > 0)
					{
						bool inMessagesHandled = nodeMessages.NodeWithInfo.Node.HandleInMessages(nodeMessages.Messages.InMessages, nodeMessages.NodeWithInfo.SyncInMessages, nodeMessages.NodeWithInfo.SkipErrorQueueForSync);
						if (!inMessagesHandled)
						{
							unhandledNodes.Add(nodeMessages);
						}
					}
					if (nodeMessages.Messages.OutMessageCount > 0)
					{
						nodeMessages.NodeWithInfo.Node.HandleOutMessages(nodeMessages.Messages.OutMessages);
					}
				}
			}

			if (unhandledNodes.Count > 0)
			{
				bool bThrow = false;
				StringBuilder detailBuilder = new StringBuilder();
				detailBuilder.Append("Error handling sync in messages\r\n");
				foreach (NodeWithMessages nwm in unhandledNodes)
				{
					if (nwm.NodeWithInfo.SkipErrorQueueForSync && nwm.NodeWithInfo.SyncInMessages)
					{
						detailBuilder.AppendFormat("Node:{0}\r\n", nwm.NodeWithInfo.Node.GetType().Name);
						detailBuilder.AppendFormat("\tMessages: {0}\r\n", nwm.Messages.InMessageCount);
						bThrow = true;
					}
				}
				if (bThrow)
				{
					throw new SyncRelayOperationException(detailBuilder.ToString());
				}


				if (_log.IsInfoEnabled)
					_log.Info(detailBuilder.ToString());

			}
		}
示例#5
0
        private static void AsyncBulkHandleMessages(NodeWithMessagesCollection distributedMessages, List <NodeWithMessages> unhandledNodes)
        {
            if (log.IsDebugEnabled)
            {
                log.Debug("Starting asyncbulk handle messages");
            }

            AutoResetEvent  resetEvent   = null;
            HandleWithCount finishedLock = null;

            int numberOfGets = 0;
            int getsLefts    = 0;

            for (int i = 0; i < distributedMessages.Count; i++)
            {
                if (distributedMessages[i].Messages.OutMessageCount > 0)
                {
                    numberOfGets++;
                }
            }

            if (numberOfGets > 0)
            {
                resetEvent   = OutMessageWaitHandle;
                finishedLock = new HandleWithCount(resetEvent, numberOfGets);
                getsLefts    = numberOfGets;              //use this to determine when we're at the last get so we use this thread to process it
            }

            for (int i = 0; i < distributedMessages.Count; i++)
            {
                NodeWithMessages nodeWithMessages = distributedMessages[i];
                NodeWithInfo     nodeWithInfo     = nodeWithMessages.NodeWithInfo;
                if (nodeWithMessages.Messages.InMessageCount > 0)
                {
                    bool inMessagesHandled = nodeWithInfo.Node.HandleInMessages(nodeWithMessages.Messages.InMessages,
                                                                                nodeWithInfo.SyncInMessages, nodeWithInfo.SkipErrorQueueForSync);
                    if (!inMessagesHandled)
                    {
                        unhandledNodes.Add(nodeWithMessages);
                    }
                }
                if (nodeWithMessages.Messages.OutMessageCount > 0)
                {
                    if (--getsLefts > 0)                     //post all the last group to be handled async
                    {
                        nodeWithInfo.Node.PostOutMessages(
                            new MessagesWithLock(nodeWithMessages.Messages.OutMessages, finishedLock));
                    }
                    else
                    {
                        nodeWithInfo.Node.SendOutMessages(nodeWithMessages.Messages.OutMessages);                         //do the last set on this thread rather than punting the duty
                        finishedLock.Decrement();
                    }
                }
            }

            if (numberOfGets > 0)
            {
                resetEvent.WaitOne();                 //wait for all operations to complete. the event will be signaled with lock.decrement hits 0
            }
        }