private void HandleQueueWorkDetectedTriggerEvent(CloudQueueWorkDetectedTriggerEvent e) { Guard.ArgumentNotNull(e, "e"); // Enumerate through registered queue listeners and relay the trigger event to them. foreach (var queueService in this.owner.Extensions.FindAll <ICloudQueueServiceWorkerRoleExtension>()) { // Pass the trigger event to a given queue listener. queueService.OnNext(e); } }
/// <summary> /// Gets called by the provider to notify this queue listener about a new trigger event. /// </summary> /// <param name="e">The trigger event indicating that a new payload was put in a queue.</param> public void OnNext(CloudQueueWorkDetectedTriggerEvent e) { Guard.ArgumentNotNull(e, "e"); var callToken = TraceManager.WorkerRoleComponent.TraceIn(e.StorageAccount, e.QueueName, e.PayloadSize); try { // Make sure the trigger event is for the queue managed by this listener, otherwise ignore. if (this.queueLocation.StorageAccount == e.StorageAccount && this.queueLocation.QueueName == e.QueueName) { if (QueueWorkDetected != null) { QueueWorkDetected(this); } } } finally { TraceManager.WorkerRoleComponent.TraceOut(callToken); } }
private void HandlePersistenceQueueItem(PersistenceQueueItemInfo itemInfo) { Guard.ArgumentNotNull(itemInfo, "itemInfo"); this.owner.Extensions.Demand <IRulesEngineServiceClientExtension>(); this.owner.Extensions.Demand <IWorkItemSchedulerConfigurationExtension>(); this.owner.Extensions.Demand <IRoleConfigurationSettingsExtension>(); this.owner.Extensions.Demand <ICloudStorageProviderExtension>(); this.owner.Extensions.Demand <IInterRoleCommunicationExtension>(); IRulesEngineServiceClientExtension rulesEngineExtension = this.owner.Extensions.Find <IRulesEngineServiceClientExtension>(); IWorkItemSchedulerConfigurationExtension configSettingsExtension = this.owner.Extensions.Find <IWorkItemSchedulerConfigurationExtension>(); IRoleConfigurationSettingsExtension roleConfigExtension = this.owner.Extensions.Find <IRoleConfigurationSettingsExtension>(); ICloudStorageProviderExtension storageProviderExtension = this.owner.Extensions.Find <ICloudStorageProviderExtension>(); IActivityTrackingEventStreamExtension trackingEventStreamExtension = this.owner.Extensions.Find <IActivityTrackingEventStreamExtension>(); IInterRoleCommunicationExtension interCommExtension = this.owner.Extensions.Find <IInterRoleCommunicationExtension>(); // Update BAM activity to indicate when we started the dequeue operation. if (trackingEventStreamExtension != null) { InventoryDataTrackingActivity activity = new InventoryDataTrackingActivity(itemInfo.QueueItemId.ToString()) { DequeueOperationStarted = DateTime.UtcNow }; trackingEventStreamExtension.UpdateActivity(activity); } var xPathLib = roleConfigExtension.GetSection <XPathQueryLibrary>(XPathQueryLibrary.SectionName); var batchInfo = rulesEngineExtension.ExecutePolicy <PersistenceQueueItemBatchInfo>(configSettingsExtension.Settings.HandlingPolicyName, itemInfo, new MessageTypeFact(itemInfo.QueueItemType)); // Verify the batch metadata to ensure we have everything we need to be able to perform de-batching. ValidateBatchMetadata(itemInfo, batchInfo); // Replace the XPath query references with actual expressions taken from the XPath Library. batchInfo.BodyItemXPath = xPathLib.Queries.Contains(batchInfo.BodyItemXPath) ? xPathLib.GetXPathQuery(batchInfo.BodyItemXPath) : batchInfo.BodyItemXPath; batchInfo.BodyItemCountXPath = xPathLib.Queries.Contains(batchInfo.BodyItemCountXPath) ? xPathLib.GetXPathQuery(batchInfo.BodyItemCountXPath) : batchInfo.BodyItemCountXPath; var headerXPathList = from item in batchInfo.HeaderSegments where xPathLib.Queries.Contains(item) select new { Segment = item, XPath = xPathLib.GetXPathQuery(item) }; var bodyXPathList = from item in batchInfo.BodySegments where xPathLib.Queries.Contains(item) select new { Segment = item, XPath = xPathLib.GetXPathQuery(item) }; var footerXPathList = from item in batchInfo.FooterSegments where xPathLib.Queries.Contains(item) select new { Segment = item, XPath = xPathLib.GetXPathQuery(item) }; foreach (var item in headerXPathList.ToList()) { batchInfo.HeaderSegments.Remove(item.Segment); batchInfo.HeaderSegments.Add(item.XPath); } foreach (var item in bodyXPathList.ToList()) { batchInfo.BodySegments.Remove(item.Segment); batchInfo.BodySegments.Add(item.XPath); } foreach (var item in footerXPathList.ToList()) { batchInfo.FooterSegments.Remove(item.Segment); batchInfo.FooterSegments.Add(item.XPath); } int fromItem = 1, toItem = fromItem, maxItems = configSettingsExtension.Settings.XmlBatchSize; var taskParameters = new List <DequeueXmlDataTaskState>(); using (SqlAzurePersistenceQueue persistenceQueue = new SqlAzurePersistenceQueue()) { persistenceQueue.Open(WellKnownDatabaseName.PersistenceQueue); using (XmlReader resultReader = persistenceQueue.QueryXmlData(itemInfo.QueueItemId, new string[] { batchInfo.BodyItemCountXPath }, xPathLib.Namespaces.NamespaceManager)) { maxItems = resultReader.ReadContentAsInt(); } } do { toItem = fromItem + configSettingsExtension.Settings.XmlBatchSize - 1; taskParameters.Add(new DequeueXmlDataTaskState() { QueueItemInfo = itemInfo, HeaderSegments = new List <string>(batchInfo.HeaderSegments), BodySegments = new List <string>(from query in batchInfo.BodySegments select String.Format(query, fromItem, toItem)), FooterSegments = new List <string>(batchInfo.FooterSegments), StartItemIndex = fromItem, EndItemIndex = toItem, ItemDetectionXPath = batchInfo.BodyItemXPath, Settings = configSettingsExtension.Settings, StorageProvider = storageProviderExtension, NamespaceManager = xPathLib.Namespaces.NamespaceManager }); fromItem += configSettingsExtension.Settings.XmlBatchSize; }while (toItem < maxItems); // Before we start putting work items on queue, notify the respective queue listeners that they should expect work to arrive. CloudQueueWorkDetectedTriggerEvent trigger = new CloudQueueWorkDetectedTriggerEvent(configSettingsExtension.Settings.CloudStorageAccount, configSettingsExtension.Settings.DestinationQueue, maxItems, PayloadSizeKind.MessageCount); // Package the trigger into an inter-role communication event. var interRoleEvent = new InterRoleCommunicationEvent(trigger); // Publish inter-role communication event via the Service Bus one-way multicast. interCommExtension.Publish(interRoleEvent); var stateCollection = from x in taskParameters.AsParallel <DequeueXmlDataTaskState>() orderby x.StartItemIndex select x; foreach (var state in stateCollection) { try { DequeueXmlDataTaskMain(state); } catch (Exception ex) { TraceManager.WorkerRoleComponent.TraceError(ex); } } // Update BAM activity to indicate when we completed the dequeue operation. if (trackingEventStreamExtension != null) { InventoryDataTrackingActivity activity = new InventoryDataTrackingActivity(itemInfo.QueueItemId.ToString()) { DequeueOperationCompleted = DateTime.UtcNow }; trackingEventStreamExtension.UpdateActivity(activity); } }