public static void ProcessMessageLoop(ref int msgProcessed, ref int msgErrors, int? invisibilityTimeout = null) { IMessageQueue queue = new AzureMessageQueue(); while (true) { try { QueueMessage payload = queue.Dequeue(invisibilityTimeout); if (payload == null) { break; } // Right now, success/failure is indicated through a bool // Do we want to surround this with a try/catch and use exceptions instead? if (ProcessMessage(payload, invisibilityTimeout)) { queue.DeleteCurrentMessage(); msgProcessed++; } else { // Leave it in the queue for retry after invisibility period expires msgErrors++; } } catch (Exception ex) { DashTrace.TraceWarning("Unhandled exception processing async message. Message will be left in queue. Details: {0}", ex); msgErrors++; } } }
public static void ProcessMessageLoop(ref int msgProcessed, ref int msgErrors, Func<QueueMessage, bool> continueLoopPostDequeue, Func<bool> continueLoopPostProcess, int? invisibilityTimeout, string namespaceAccount, string queueName) { CloudStorageAccount newNamespace = null; if (!String.IsNullOrWhiteSpace(namespaceAccount)) { if (CloudStorageAccount.TryParse(namespaceAccount, out newNamespace)) { DashConfiguration.NamespaceAccount = newNamespace; } } if (DashConfiguration.NamespaceAccount == null) { DashTrace.TraceWarning("Namespace account configuration not set. Asynchronous processing cannot continue."); return; } IMessageQueue queue = new AzureMessageQueue(newNamespace, queueName); do { try { QueueMessage payload = queue.Dequeue(invisibilityTimeout); if (!continueLoopPostDequeue(payload)) { break; } // Right now, success/failure is indicated through a bool // Do we want to surround this with a try/catch and use exceptions instead? if (payload != null) { if (ProcessMessage(payload, invisibilityTimeout) || payload.AbandonOperation) { payload.Delete(); msgProcessed++; } else { // Leave it in the queue for retry after invisibility period expires msgErrors++; } } } catch (Exception ex) { DashTrace.TraceWarning("Unhandled exception processing async message. Message will be left in queue. Details: {0}", ex); msgErrors++; } } while (continueLoopPostProcess()); }
void AssertReplicationMessageIsEnqueued(MessageTypes messageType, string container, string blobName, string primaryAccount) { // Wait for the messages to be fully enqueued Task.Delay(1000).Wait(); var queue = new AzureMessageQueue(); var replicaAccounts = DashConfiguration.DataAccounts .Select(account => account.Credentials.AccountName) .Where(accountName => !String.Equals(accountName, primaryAccount, StringComparison.OrdinalIgnoreCase)) .ToDictionary(accountName => accountName, accountName => false, StringComparer.OrdinalIgnoreCase); while (true) { var replicateMessage = queue.Dequeue(); if (replicateMessage == null) { break; } Assert.IsNotNull(replicateMessage); Assert.AreEqual(replicateMessage.MessageType, messageType); if (messageType == MessageTypes.BeginReplicate) { Assert.AreEqual(replicateMessage.Payload[ReplicatePayload.Source], primaryAccount); } Assert.AreEqual(replicateMessage.Payload[ReplicatePayload.Container], container); Assert.AreEqual(replicateMessage.Payload[ReplicatePayload.BlobName], blobName); replicaAccounts[replicateMessage.Payload[messageType == MessageTypes.BeginReplicate ? ReplicatePayload.Destination : ReplicatePayload.Source]] = true; queue.DeleteCurrentMessage(); } Assert.IsFalse(replicaAccounts.Any(account => !account.Value), "Data accounts detected with no replication enqueued: {0}", String.Join(", ", replicaAccounts .Where(account => !account.Value) .Select(account => account.Key))); }
void AssertQueueIsDrained() { // Wait for the messages to be fully enqueued Task.Delay(1000).Wait(); bool messageSeen = false; var queue = new AzureMessageQueue(); while (true) { var message = queue.Dequeue(); if (message == null) { break; } queue.DeleteCurrentMessage(); messageSeen = true; } if (messageSeen) { Assert.Fail("Expected queue to be empty"); } }