Exemplo n.º 1
0
        // Handle poison message exception by moving the poison message out of the way for regular processing to continue.
        public bool HandleError(Exception error)
        {
            MsmqPoisonMessageException poisonException = error as MsmqPoisonMessageException;

            if (null != poisonException)
            {
                long lookupId = poisonException.MessageLookupId;
                Console.WriteLine(" Poisoned message -message look up id = {0}", lookupId);

                // Get MSMQ queue name from app settings in configuration.

                System.Messaging.MessageQueue orderQueue         = new System.Messaging.MessageQueue(OrderProcessorService.QueueName);
                System.Messaging.MessageQueue poisonMessageQueue = new System.Messaging.MessageQueue(OrderProcessorService.PoisonQueueName);
                System.Messaging.Message      message            = null;

                // Use a new transaction scope to remove the message from the main app queue and add it to the poison queue
                // the poison message service processes messages from the poison queue.
                using (TransactionScope txScope = new TransactionScope(TransactionScopeOption.RequiresNew))
                {
                    int retryCount = 0;
                    while (retryCount < 3)
                    {
                        retryCount++;

                        try
                        {
                            // Look up the poison message using the look up id.
                            message = orderQueue.ReceiveByLookupId(lookupId);
                            if (message != null)
                            {
                                // send the message to the poison message queue.
                                poisonMessageQueue.Send(message, System.Messaging.MessageQueueTransactionType.Automatic);

                                // complete transaction scope
                                txScope.Complete();

                                Console.WriteLine("Moved poisoned message with look up id: {0} to poison queue: {1} ", lookupId, OrderProcessorService.PoisonQueueName);
                                break;
                            }
                        }
                        catch (InvalidOperationException)
                        {
                            //Code for the case when the message may still not be available in the queue because of a race condition in the transaction or
                            //another node in the farm may actually have taken the message.
                            if (retryCount < 3)
                            {
                                Console.WriteLine("Trying to move poison message but message is not available, sleeping for 10 seconds before retrying");
                                Thread.Sleep(TimeSpan.FromSeconds(10));
                            }
                            else
                            {
                                Console.WriteLine("Giving up on trying to move the message");
                            }
                        }
                    }
                }

                // restart service host
                Console.WriteLine();
                Console.WriteLine("Restarting the service to process rest of the messages in the queue");
                Console.WriteLine("Press <ENTER> to stop the service");
                ThreadPool.QueueUserWorkItem(orderProcessingCallback);
                return(true);
            }

            return(false);
        }
Exemplo n.º 2
0
        // Handle poison message exception by moving the offending message out of the way for regular processing to go on.
        public bool HandleError(Exception error)
        {
            MsmqPoisonMessageException poisonException = error as MsmqPoisonMessageException;
            if (null != poisonException)
            {
                long lookupId = poisonException.MessageLookupId;
                Console.WriteLine(" Poisoned message -message look up id = {0}", lookupId);

                // Get MSMQ queue name from app settings in configuration.

                System.Messaging.MessageQueue orderQueue = new System.Messaging.MessageQueue(Poisoned.WcfService.Properties.Settings.Default.QueueName);
                System.Messaging.MessageQueue poisonMessageQueue = new System.Messaging.MessageQueue(Poisoned.WcfService.Properties.Settings.Default.PoisonQueueName);
                System.Messaging.Message message = null;

                // Use a new transaction scope to remove the message from the main application queue and add it to the poison queue.
                // The poison message service processes messages from the poison queue.
                using (TransactionScope txScope = new TransactionScope(TransactionScopeOption.RequiresNew))
                {
                    int retryCount = 0;
                    while (retryCount < 3)
                    {
                        retryCount++;

                        try
                        {
                            // Look up the poison message using the look up id.
                            message = orderQueue.ReceiveByLookupId(lookupId);
                            if (message != null)
                            {
                                // Send the message to the poison message queue.
                                poisonMessageQueue.Send(message, System.Messaging.MessageQueueTransactionType.Automatic);

                                // complete transaction scope
                                txScope.Complete();

                                Console.WriteLine("Moved poisoned message with look up id: {0} to poison queue: {1} ", lookupId, Poisoned.WcfService.Properties.Settings.Default.PoisonQueueName);
                                break;
                            }

                        }
                        catch (InvalidOperationException)
                        {
                            //Code for the case when the message may still not be available in the queue because of a race condition in transaction or 
                            //another node in the farm may actually have taken the message.
                            if (retryCount < 3)
                            {
                                Console.WriteLine("Trying to move poison message but message is not available, sleeping for 10 seconds before retrying");
                                Thread.Sleep(TimeSpan.FromSeconds(10));
                            }
                            else
                            {
                                Console.WriteLine("Giving up on trying to move the message");
                            }
                        }

                    }
                }

                // Restart the service host.
                Console.WriteLine();
                Console.WriteLine("Restarting the service to process rest of the messages in the queue");
                Console.WriteLine("Press <ENTER> to stop the service");
                //ThreadPool.QueueUserWorkItem(orderProcessingCallback);
                return true;
            }

            return false;
        }
 // Handle poison message exception by moving the offending message out of the way for regular processing to go on.
 public bool HandleError(Exception error)
 {
     MsmqPoisonMessageException poisonException = error as MsmqPoisonMessageException;
     //Note--we only want to handle poison messages coming from a durable/transacted MSMQ here.
     //So if this is not the exception type, don't do anything.  Note that errors on
     //TCP, HTTP and non-transacted (volatile) MSMQ bindings for the Trade Service will attempt,
     //on their own, to send an order to the poison queue if an exception occurs.  However, a poison
     //message in a durable queue is a special, important case that is handled here such that the
     //order message is never lost, yet is removed from the main processing queue so processing
     //is not interrupted and the queue is kept "clean."
     if (null != poisonException)
     {
         // Use a new transaction scope to remove the message from the main application queue and add it to the poison queue.
         // The poison message service processes messages from the poison queue.
         using (TransactionScope txScope = new TransactionScope(TransactionScopeOption.RequiresNew))
         {
             long lookupId = poisonException.MessageLookupId;
             ConfigUtility.writeErrorConsoleMessage(" Poisoned message: message look up id = " + lookupId + "\n",EventLogEntryType.Information,true,new Settings());
             // Get MSMQ queue name from app settings in configuration.
             if (!System.Messaging.MessageQueue.Exists(Settings.QUENAMEPOISON))
             {
                 ConfigUtility.writeErrorConsoleMessage("Creating Poison Message Queue: \n", EventLogEntryType.Information, true, new Settings());
                 ConfigUtility.writeErrorConsoleMessage(Settings.QUENAMEPOISON + "\n\n", EventLogEntryType.Information, true, new Settings());
                 System.Messaging.MessageQueue.Create(Settings.QUENAMEPOISON, true);
             }
             HostedServices opsService = Settings.hostedServices.Find(delegate(HostedServices hs) { return (hs.BindingType.Equals(ConfigUtility.NET_MSMQ_BINDING)); });
             string tempqueuenametx = @".\private$\" + opsService.VirtualPath;
             System.Messaging.MessageQueue orderQueue = new System.Messaging.MessageQueue(tempqueuenametx);
             System.Messaging.MessageQueue poisonMessageQueue = new System.Messaging.MessageQueue(Settings.QUENAMEPOISON);
             System.Messaging.Message message = null;
        
             int retryCount = 0;
             while (retryCount < 4)
             {
                 retryCount++;
                 try
                 {
                     // Look up the poison message using the look up id.
                     message = orderQueue.ReceiveByLookupId(lookupId);
                     if (message != null)
                     {
                         // Send the message to the poison message queue.
                         if (Settings.NOPOISONQUEUE)
                         {
                             ConfigUtility.writeErrorConsoleMessage("Running in /nopoisonq mode:  message is being removed and discarded!\n", EventLogEntryType.Warning, true, new Settings());
                             txScope.Complete();
                             break;
                         }
                         else
                         {
                             poisonMessageQueue.Send(message, System.Messaging.MessageQueueTransactionType.Automatic);
                             // complete transaction scope
                             txScope.Complete();
                             string writemessage = string.Format("Moved poisoned message with look up id: {0} to poison queue: {1} ", lookupId, Settings.QUENAMEPOISON);
                             ConfigUtility.writeErrorConsoleMessage(writemessage + "\n\n", EventLogEntryType.Information, true, new Settings());
                             break;
                         }
                     }
                 }
                 catch (InvalidOperationException)
                 {
                     //Code for the case when the message may still not be available in the queue because of a race in transaction or 
                     //another node in the farm may actually have taken the message.
                     if (retryCount < 2)
                     {
                         ConfigUtility.writeErrorConsoleMessage("Trying to move poison message but message is not available.  Will retry in 500 ms. \n", EventLogEntryType.Warning, true, new Settings());
                         Thread.Sleep(1000);
                     }
                     else
                     {
                        //The message will remain in the main queue in this condition. 
                         ConfigUtility.writeErrorConsoleMessage("Giving up on trying to move the message:  May have been automatically moved already to the local retry queue on Vista/Win Server 2008 depending on binding setting!\n", EventLogEntryType.Warning, true, new Settings());
                     }
                 }
             }
         }
         return true;
     }
     return false;
 }