private void ReceiveMessage(object context) { int sleepTime = 1; while (shouldContinue) { Thread.Sleep(sleepTime); try { using (var tx = _sqlQueueManager.BeginTransaction()) { if (!_sqlQueueManager.Peek(_queueId)) { sleepTime += 100; sleepTime = Math.Min(sleepTime, SleepMax); continue; } sleepTime = 1; tx.Transaction.Commit(); } } catch (TimeoutException) { logger.DebugFormat("Could not find a message on {0} during the timeout period", queueEndpoint); continue; } catch(SqlException e) { logger.Debug("Could not get message from database.", e); continue; } catch (ObjectDisposedException) { logger.DebugFormat("Shutting down the transport for {0} thread {1}", queueEndpoint, context); return; } catch (InvalidOperationException e) { logger.Error( "An error occured while recieving a message, shutting down message processing thread", e); return; } if (shouldContinue == false) return; Message message; try { using (var tx = _sqlQueueManager.BeginTransaction()) { message = _sqlQueueManager.Receive(_queueId, TimeSpan.FromSeconds(10)); tx.Transaction.Commit(); } } catch (TimeoutException) { logger.DebugFormat("Could not find a message on {0} during the timeout period", queueEndpoint); continue; } catch (SqlException e) { logger.Debug("Could not get message from database.", e); continue; } catch (Exception e) { logger.Error( "An error occured while recieving a message, shutting down message processing thread", e); return; } if (message.ProcessedCount > numberOfRetries) { using (var tx = _sqlQueueManager.BeginTransaction()) { Queue.MoveTo(SubQueue.Errors.ToString(), message); Queue.EnqueueDirectlyTo(SubQueue.Errors.ToString(), new MessagePayload { SentAt = DateTime.Now, Data = null, Headers = new NameValueCollection { { "correlation-id", message.Id.ToString() }, { "retries", message.ProcessedCount.ToString(CultureInfo.InvariantCulture) } } }); tx.Transaction.Commit(); } continue; } var messageWithTimer = new MessageWithTimer {Message = message}; var messageProcessingTimer = new Timer(extendMessageLeaaseIfMessageStillInProgress, messageWithTimer, TimeSpan.FromSeconds(40), TimeSpan.FromMilliseconds(-1)); messageWithTimer.Timer = messageProcessingTimer; try { var msgType = (MessageType) Enum.Parse(typeof (MessageType), message.Headers["type"]); logger.DebugFormat("Starting to handle message {0} of type {1} on {2}", message.Id, msgType, queueEndpoint); switch (msgType) { case MessageType.AdministrativeMessageMarker: ProcessMessage(message, AdministrativeMessageArrived, AdministrativeMessageProcessingCompleted, null, null); break; case MessageType.ShutDownMessageMarker: //ignoring this one using(var tx = _sqlQueueManager.BeginTransaction()) { _sqlQueueManager.MarkMessageAsReady(message); tx.Transaction.Commit(); } break; case MessageType.TimeoutMessageMarker: var timeToSend = XmlConvert.ToDateTime(message.Headers["time-to-send"], XmlDateTimeSerializationMode.Unspecified); if (timeToSend > DateTime.Now) { timeout.Register(message); using (var tx = queue.BeginTransaction()) { queue.MoveTo(SubQueue.Timeout.ToString(), message); tx.Transaction.Commit(); } } else { ProcessMessage(message, MessageArrived, MessageProcessingCompleted, BeforeMessageTransactionCommit, BeforeMessageTransactionRollback); } break; default: ProcessMessage(message, MessageArrived, MessageProcessingCompleted, BeforeMessageTransactionCommit, BeforeMessageTransactionRollback); break; } } catch (Exception exception) { logger.Debug("Could not process message", exception); } message.FinishedProcessing = true; } }
private void ReceiveMessage(object context) { int sleepTime = 1; while (shouldContinue) { Thread.Sleep(sleepTime); try { using (var tx = _sqlQueueManager.BeginTransaction()) { if (!_sqlQueueManager.Peek(_queueId)) { sleepTime += 100; sleepTime = Math.Min(sleepTime, SleepMax); continue; } sleepTime = 1; tx.Transaction.Commit(); } } catch (TimeoutException) { logger.DebugFormat("Could not find a message on {0} during the timeout period.", queueEndpoint); continue; } catch (SqlException e) { logger.Warn("Could not get message from database.", e); continue; } catch (ObjectDisposedException) { logger.DebugFormat("Shutting down the transport for {0} thread {1}.", queueEndpoint, context); return; } catch (InvalidOperationException e) { logger.Error( "An error occured while recieving a message, clearing connection pool and make a new attempt after some sleep.", e); SqlConnection.ClearAllPools(); sleepTime = SleepMax; continue; } catch (Exception e) { logger.Error( "An error occured while recieving a message, shutting down message processing thread", e); return; } if (shouldContinue == false) { return; } Message message; try { using (var tx = _sqlQueueManager.BeginTransaction()) { message = _sqlQueueManager.Receive(_queueId, TimeSpan.FromSeconds(10)); tx.Transaction.Commit(); } } catch (TimeoutException) { logger.DebugFormat("Could not find a message on {0} during the timeout period", queueEndpoint); continue; } catch (SqlException e) { logger.Debug("Could not get message from database.", e); continue; } catch (InvalidOperationException e) { logger.Error( "An error occured while recieving a message, clearing connection pool and make a new attempt after some sleep.", e); SqlConnection.ClearAllPools(); sleepTime = SleepMax; continue; } catch (Exception e) { logger.Error( "An error occured while recieving a message, shutting down message processing thread", e); return; } if (message.ProcessedCount > numberOfRetries) { using (var tx = _sqlQueueManager.BeginTransaction()) { Queue.MoveTo(SubQueue.Errors.ToString(), message); Queue.EnqueueDirectlyTo(SubQueue.Errors.ToString(), new MessagePayload { SentAt = DateTime.UtcNow, Data = null, Headers = new NameValueCollection { { "correlation-id", message.Id.ToString() }, { "retries", message.ProcessedCount.ToString(CultureInfo.InvariantCulture) } } }); tx.Transaction.Commit(); } continue; } var messageWithTimer = new MessageWithTimer { Message = message }; var messageProcessingTimer = new Timer(extendMessageLeaaseIfMessageStillInProgress, messageWithTimer, TimeSpan.FromSeconds(40), TimeSpan.FromMilliseconds(-1)); messageWithTimer.Timer = messageProcessingTimer; try { var msgType = (MessageType)Enum.Parse(typeof(MessageType), message.Headers["type"]); logger.DebugFormat("Starting to handle message {0} of type {1} on {2}", message.Id, msgType, queueEndpoint); switch (msgType) { case MessageType.AdministrativeMessageMarker: ProcessMessage(message, AdministrativeMessageArrived, AdministrativeMessageProcessingCompleted, null, null); break; case MessageType.ShutDownMessageMarker: //ignoring this one using (var tx = _sqlQueueManager.BeginTransaction()) { _sqlQueueManager.MarkMessageAsReady(message); tx.Transaction.Commit(); } break; case MessageType.TimeoutMessageMarker: var timeToSend = XmlConvert.ToDateTime(message.Headers["time-to-send"], XmlDateTimeSerializationMode.Unspecified); if (timeToSend > DateTime.Now) { timeout.Register(message); using (var tx = queue.BeginTransaction()) { queue.MoveTo(SubQueue.Timeout.ToString(), message); tx.Transaction.Commit(); } } else { ProcessMessage(message, MessageArrived, MessageProcessingCompleted, BeforeMessageTransactionCommit, BeforeMessageTransactionRollback); } break; default: ProcessMessage(message, MessageArrived, MessageProcessingCompleted, BeforeMessageTransactionCommit, BeforeMessageTransactionRollback); break; } } catch (Exception exception) { logger.Debug("Could not process message", exception); } message.FinishedProcessing = true; } }