コード例 #1
0
        public void OnMessage(IRestrictionAttributesAcceptedV1 message)
        {
            var requestTelemetry = RequestTelemetryHelper.Start("Restriction Attributes Accepted Processing Rate", DateTime.UtcNow);

            CallContext.LogicalSetData(CORRELATION_SLOT, requestTelemetry.Id);
            Stopwatch requestTimer = Stopwatch.StartNew();

            if (message == null)
            {
                throw new ArgumentNullException();
            }

            var skuVariant = _skuVariantCacheManager.GetItemByKey(message.Sku);

            if (skuVariant == null)
            {
                throw new Exception($"Sku Variant Not Found For Restriction Attribute Accepted with Sku: {message.Sku}");
            }

            var regionStock = _regionStockAggregateStore.GetRegionStockByVariantId(skuVariant.VariantId);

            if (regionStock != null)
            {
                IRegionStockAggregate regionStockAggregate = new RegionStockAggregate(regionStock.VariantId,
                                                                                      regionStock.WarehouseAvailableStocks.ToList(),
                                                                                      regionStock.RegionStocks.ToList(), null, regionStock.Version);

                regionStockAggregate.ApplyRestrictionAttributes(message.Attributes);

                _regionStockAggregateStore.UpdateRegionStock(RegionStockDocument.CreateFrom(regionStockAggregate));
            }
            else
            {
                throw new RegionStockAggregateNotFoundException($"Failed retrieving Region Stock Aggregate for Sku {message.Sku}");
            }

            RequestTelemetryHelper.Dispatch(_telemetryClient, requestTelemetry, requestTimer.Elapsed, true);
        }
コード例 #2
0
        private void ProcessSubscribeQueueMessage(CloudQueueMessage msg)
        {
            Stopwatch requestTimer = Stopwatch.StartNew();
            var       request      = RequestTelemetryHelper.StartNewRequest("ProcessSubscribeQueueMessage", DateTimeOffset.UtcNow);

            CallContext.LogicalSetData(CORRELATION_SLOT, request.Id);
            //Thread.SetData(Thread.GetNamedDataSlot(CORRELATION_SLOT), request.Id);
            try
            {
                // Log and delete if this is a "poison" queue message (repeatedly processed
                // and always causes an error that prevents processing from completing).
                // Production applications should move the "poison" message to a "dead message"
                // queue for analysis rather than deleting the message.
                if (msg.DequeueCount > 5)
                {
                    Trace.TraceError("Deleting poison subscribe message:    message {0}.",
                                     msg.AsString, GetRoleInstance());
                    subscribeQueue.DeleteMessage(msg);
                    request.Properties.Add(new KeyValuePair <string, string>("FailureCode", "PoisonMessage"));
                    request.Properties.Add(new KeyValuePair <string, string>("DequeueCount", msg.DequeueCount.ToString()));
                    if (msg.InsertionTime != null)
                    {
                        request.Metrics.Add(new KeyValuePair <string, double>("SubscribeProcessingTimeMs", ((TimeSpan)(DateTimeOffset.Now - msg.InsertionTime)).Milliseconds));
                    }
                    RequestTelemetryHelper.DispatchRequest(request, requestTimer.Elapsed, false);
                    return;
                }
                // Parse message retrieved from queue. Message consists of
                // subscriber GUID and list name.
                // Example:  57ab4c4b-d564-40e3-9a3f-81835b3e102e,contoso1
                var messageParts   = msg.AsString.Split(new char[] { ',' });
                var subscriberGUID = messageParts[0];
                var listName       = messageParts[1];
                Trace.TraceInformation("ProcessSubscribeQueueMessage start:    subscriber GUID {0} listName {1} Role Instance {2}.",
                                       subscriberGUID, listName, GetRoleInstance());
                // Get subscriber info.
                string filter = TableQuery.CombineFilters(
                    TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, listName),
                    TableOperators.And,
                    TableQuery.GenerateFilterCondition("SubscriberGUID", QueryComparisons.Equal, subscriberGUID));
                var query      = new TableQuery <Subscriber>().Where(filter);
                var subscriber = mailingListTable.ExecuteQuery(query).ToList().Single();
                // Get mailing list info.
                var retrieveOperation = TableOperation.Retrieve <MailingList>(subscriber.ListName, "mailinglist");
                var retrievedResult   = mailingListTable.Execute(retrieveOperation);
                var mailingList       = retrievedResult.Result as MailingList;

                SendSubscribeEmail(subscriberGUID, subscriber, mailingList);

                subscribeQueue.DeleteMessage(msg);

                Trace.TraceInformation("ProcessSubscribeQueueMessage complete: subscriber GUID {0} Role Instance {1}.", subscriberGUID, GetRoleInstance());
                if (msg.InsertionTime != null)
                {
                    request.Metrics.Add(new KeyValuePair <string, double>("SubscribeProcessingTimeMs", ((TimeSpan)(DateTimeOffset.Now - msg.InsertionTime)).Milliseconds));
                }
                RequestTelemetryHelper.DispatchRequest(request, requestTimer.Elapsed, true);
            }
            catch (Exception ex)
            {
                request.Properties.Add(new KeyValuePair <string, string>("FailureCode", "Exception"));
                if (msg.InsertionTime != null)
                {
                    request.Metrics.Add(new KeyValuePair <string, double>("FailedSubscribeProcessingTimeMs", ((TimeSpan)(DateTimeOffset.Now - msg.InsertionTime)).Milliseconds));
                }
                RequestTelemetryHelper.DispatchRequest(request, requestTimer.Elapsed, false);
                throw ex;
            }
        }
コード例 #3
0
        public override void Run()
        {
            Trace.TraceInformation("WorkerRoleA entering Run()");
            while (true)
            {
                Stopwatch requestTimer = Stopwatch.StartNew();
                var       request      = RequestTelemetryHelper.StartNewRequest("ProcessMessageWorkflow", DateTimeOffset.UtcNow);
                CallContext.LogicalSetData(CORRELATION_SLOT, request.Id);
                //Thread.SetData(Thread.GetNamedDataSlot(CORRELATION_SLOT), request.Id);
                try
                {
                    var tomorrow = DateTime.Today.AddDays(1.0).ToString("yyyy-MM-dd");
                    // If OnStop has been called, return to do a graceful shutdown.
                    if (onStopCalled == true)
                    {
                        Trace.TraceInformation("onStopCalled WorkerRoleB");
                        returnedFromRunMethod = true;
                        return;
                    }

                    // Retrieve all messages that are scheduled for tomorrow or earlier
                    // and are in Pending or Queuing status.
                    string typeAndDateFilter = TableQuery.CombineFilters(
                        TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.GreaterThan, "message"),
                        TableOperators.And,
                        TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.LessThan, tomorrow));
                    var            query             = (new TableQuery <Message>().Where(typeAndDateFilter));
                    var            messagesToProcess = messageTable.ExecuteQuery(query).ToList();
                    TableOperation replaceOperation;
                    request.Metrics.Add(new KeyValuePair <string, double>("NumberOfMessages", messagesToProcess.Count));
                    // Process each message (queue emails to be sent).
                    foreach (Message messageToProcess in messagesToProcess)
                    {
                        string restartFlag = "0";
                        // If the message is already in Queuing status,
                        // set flag to indicate this is a restart.
                        if (messageToProcess.Status == "Queuing")
                        {
                            restartFlag = "1";
                        }

                        // If the message is in Pending status, change
                        // it to Queuing.
                        if (messageToProcess.Status == "Pending")
                        {
                            messageToProcess.Status = "Queuing";
                            replaceOperation        = TableOperation.Replace(messageToProcess);
                            messageTable.Execute(replaceOperation);
                        }

                        // If the message is in Queuing status,
                        // process it and change it to Processing status;
                        // otherwise it's already in processing status, and
                        // in that case check if processing is complete.
                        if (messageToProcess.Status == "Queuing")
                        {
                            ProcessMessage(messageToProcess, restartFlag);

                            messageToProcess.Status = "Processing";
                            replaceOperation        = TableOperation.Replace(messageToProcess);
                            messageTable.Execute(replaceOperation);
                        }
                        else
                        {
                            CheckAndArchiveIfComplete(messageToProcess);
                        }
                    }
                    RequestTelemetryHelper.DispatchRequest(request, requestTimer.Elapsed, true);
                    // Sleep to minimize query costs.
                    System.Threading.Thread.Sleep(1000 * 30);
                }
                catch (Exception ex)
                {
                    string err = ex.Message;
                    if (ex.InnerException != null)
                    {
                        err += " Inner Exception: " + ex.InnerException.Message;
                    }
                    Trace.TraceError(err, ex);
                    RequestTelemetryHelper.DispatchRequest(request, requestTimer.Elapsed, false);
                    // Don't fill up Trace storage if we have a bug in queue process loop.
                    System.Threading.Thread.Sleep(1000 * 60);
                }
            }
        }
コード例 #4
0
        private void ProcessQueueMessage(CloudQueueMessage msg)
        {
            Stopwatch requestTimer = Stopwatch.StartNew();
            var       request      = RequestTelemetryHelper.StartNewRequest("ProcessEmailQueueMessage", DateTimeOffset.UtcNow);

            CallContext.LogicalSetData(CORRELATION_SLOT, request.Id);
            //Thread.SetData(Thread.GetNamedDataSlot(CORRELATION_SLOT), request.Id);
            try
            {
                // Log and delete if this is a "poison" queue message (repeatedly processed
                // and always causes an error that prevents processing from completing).
                // Production applications should move the "poison" message to a "dead message"
                // queue for analysis rather than deleting the message.
                if (msg.DequeueCount > 5)
                {
                    Trace.TraceError("Deleting poison message:    message {0} Role Instance {1}.",
                                     msg.ToString(), GetRoleInstance());
                    sendEmailQueue.DeleteMessage(msg);
                    request.Properties.Add(new KeyValuePair <string, string>("FailureCode", "PoisonMessage"));
                    request.Properties.Add(new KeyValuePair <string, string>("DequeueCount", msg.DequeueCount.ToString()));
                    if (msg.InsertionTime != null)
                    {
                        request.Metrics.Add(new KeyValuePair <string, double>("EmailProcessingTimeMs", ((TimeSpan)(DateTimeOffset.Now - msg.InsertionTime)).Milliseconds));
                    }
                    RequestTelemetryHelper.DispatchRequest(request, requestTimer.Elapsed, false);
                    return;
                }
                // Parse message retrieved from queue.
                // Example:  2012-01-01,[email protected],0
                var messageParts = msg.AsString.Split(new char[] { ',' });
                var partitionKey = messageParts[0];
                var rowKey       = messageParts[1];
                var restartFlag  = messageParts[2];
                Trace.TraceInformation("ProcessQueueMessage start:  partitionKey {0} rowKey {1} Role Instance {2}.", partitionKey, rowKey, GetRoleInstance());
                // If this is a restart, verify that the email hasn't already been sent.
                if (restartFlag == "1")
                {
                    var retrieveOperationForRestart = TableOperation.Retrieve <SendEmail>(partitionKey, rowKey);
                    var retrievedResultForRestart   = messagearchiveTable.Execute(retrieveOperationForRestart);
                    var messagearchiveRow           = retrievedResultForRestart.Result as SendEmail;
                    if (messagearchiveRow != null)
                    {
                        // SendEmail row is in archive, so email is already sent.
                        // If there's a SendEmail Row in message table, delete it,
                        // and delete the queue message.
                        Trace.TraceInformation("Email already sent: partitionKey=" + partitionKey + " rowKey= " + rowKey);
                        var deleteOperation = TableOperation.Delete(new SendEmail {
                            PartitionKey = partitionKey, RowKey = rowKey, ETag = "*"
                        });
                        try
                        {
                            messageTable.Execute(deleteOperation);
                        }
                        catch (Exception ex)
                        {
                            aiClient.TrackException(ex);
                        }
                        sendEmailQueue.DeleteMessage(msg);
                        request.Properties.Add(new KeyValuePair <string, string>("SuccessCode", "NoOp-MessageAlreadySent"));
                        if (msg.InsertionTime != null)
                        {
                            request.Metrics.Add(new KeyValuePair <string, double>("EmailProcessingTimeMs", ((TimeSpan)(DateTimeOffset.Now - msg.InsertionTime)).Milliseconds));
                        }
                        RequestTelemetryHelper.DispatchRequest(request, requestTimer.Elapsed, true);
                        return;
                    }
                }
                // Get the row in the Message table that has data we need to send the email.
                var retrieveOperation      = TableOperation.Retrieve <SendEmail>(partitionKey, rowKey);
                var retrievedResult        = messageTable.Execute(retrieveOperation);
                var emailRowInMessageTable = retrievedResult.Result as SendEmail;
                if (emailRowInMessageTable == null)
                {
                    Trace.TraceError("SendEmail row not found:  partitionKey {0} rowKey {1} Role Instance {2}.", partitionKey, rowKey, GetRoleInstance());
                    request.Properties.Add(new KeyValuePair <string, string>("FailureCode", "SendEmailRowNotFound"));
                    if (msg.InsertionTime != null)
                    {
                        request.Metrics.Add(new KeyValuePair <string, double>("EmailProcessingTimeMs", ((TimeSpan)(DateTimeOffset.Now - msg.InsertionTime)).Milliseconds));
                    }
                    RequestTelemetryHelper.DispatchRequest(request, requestTimer.Elapsed, false);
                    return;
                }
                // Derive blob names from the MessageRef.
                var htmlMessageBodyRef = emailRowInMessageTable.MessageRef + ".htm";
                var textMessageBodyRef = emailRowInMessageTable.MessageRef + ".txt";
                // If the email hasn't already been sent, send email and archive the table row.
                if (emailRowInMessageTable.EmailSent != true)
                {
                    SendEmailToList(emailRowInMessageTable, htmlMessageBodyRef, textMessageBodyRef);

                    var emailRowToDelete = new SendEmail {
                        PartitionKey = partitionKey, RowKey = rowKey, ETag = "*"
                    };
                    emailRowInMessageTable.EmailSent = true;

                    var upsertOperation = TableOperation.InsertOrReplace(emailRowInMessageTable);
                    messagearchiveTable.Execute(upsertOperation);
                    var deleteOperation = TableOperation.Delete(emailRowToDelete);
                    messageTable.Execute(deleteOperation);
                }

                // Delete the queue message.
                sendEmailQueue.DeleteMessage(msg);
                Trace.TraceInformation("ProcessQueueMessage complete:  partitionKey {0} rowKey {1} Role Instance {2}.", partitionKey, rowKey, GetRoleInstance());
                request.Properties.Add(new KeyValuePair <string, string>("SuccessCode", "EmailSent"));
                if (msg.InsertionTime != null)
                {
                    request.Metrics.Add(new KeyValuePair <string, double>("EmailProcessingTimeMs", ((TimeSpan)(DateTimeOffset.Now - msg.InsertionTime)).Milliseconds));
                }
                RequestTelemetryHelper.DispatchRequest(request, requestTimer.Elapsed, true);
            }
            catch (Exception ex)
            {
                request.Properties.Add(new KeyValuePair <string, string>("FailureCode", "Exception"));
                if (msg.InsertionTime != null)
                {
                    request.Metrics.Add(new KeyValuePair <string, double>("FailedEmailProcessingTimeMs", ((TimeSpan)(DateTimeOffset.Now - msg.InsertionTime)).Milliseconds));
                }
                RequestTelemetryHelper.DispatchRequest(request, requestTimer.Elapsed, false);
                throw ex;
            }
        }