public void Constructor_DefaultsValues() { var options = new QueuesOptions { BatchSize = 32, MaxDequeueCount = 2, NewBatchThreshold = 100, VisibilityTimeout = TimeSpan.FromSeconds(30), MaxPollingInterval = TimeSpan.FromSeconds(15) }; QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(_queue, null, options); QueueProcessor localProcessor = new QueueProcessor(context); Assert.Equal(options.BatchSize, localProcessor.BatchSize); Assert.Equal(options.MaxDequeueCount, localProcessor.MaxDequeueCount); Assert.Equal(options.NewBatchThreshold, localProcessor.NewBatchThreshold); Assert.Equal(options.VisibilityTimeout, localProcessor.VisibilityTimeout); Assert.Equal(options.MaxPollingInterval, localProcessor.MaxPollingInterval); }
public QueueProcessor Create(QueueProcessorFactoryContext context) { // demonstrates how the Queue.ServiceClient options can be configured context.Queue.ServiceClient.DefaultRequestOptions.ServerTimeout = TimeSpan.FromSeconds(30); // demonstrates how queue options can be customized context.Queue.EncodeMessage = true; // demonstrates how batch processing behavior and other knobs // can be customized context.BatchSize = 30; context.NewBatchThreshold = 100; context.MaxPollingInterval = TimeSpan.FromSeconds(15); CustomQueueProcessor processor = new CustomQueueProcessor(context); CustomQueueProcessors.Add(processor); return(processor); }
public void Constructor_DefaultsValues() { var config = new JobHostQueuesConfiguration { BatchSize = 32, MaxDequeueCount = 2, NewBatchThreshold = 100, VisibilityTimeout = TimeSpan.FromSeconds(30), MaxPollingInterval = TimeSpan.FromSeconds(15) }; QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(_queue, _trace, config); QueueProcessor localProcessor = new QueueProcessor(context); Assert.Equal(config.BatchSize, localProcessor.BatchSize); Assert.Equal(config.MaxDequeueCount, localProcessor.MaxDequeueCount); Assert.Equal(config.NewBatchThreshold, localProcessor.NewBatchThreshold); Assert.Equal(config.VisibilityTimeout, localProcessor.VisibilityTimeout); Assert.Equal(config.MaxPollingInterval, localProcessor.MaxPollingInterval); }
public void Constructor_DefaultsValues() { CloudQueue queue = new CloudQueue(new Uri("https://test.queue.core.windows.net/testqueue")); CloudQueue poisonQueue = new CloudQueue(new Uri("https://test.queue.core.windows.net/poisonqueue")); ILoggerFactory loggerFactory = new LoggerFactory(); loggerFactory.AddProvider(new TestLoggerProvider()); JobHostQueuesConfiguration queuesConfig = new JobHostQueuesConfiguration(); QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(queue, loggerFactory, queuesConfig, poisonQueue); Assert.Same(queue, context.Queue); Assert.Same(poisonQueue, context.PoisonQueue); Assert.NotNull(context.Logger); Assert.Equal(queuesConfig.BatchSize, context.BatchSize); Assert.Equal(queuesConfig.NewBatchThreshold, context.NewBatchThreshold); Assert.Equal(queuesConfig.MaxDequeueCount, context.MaxDequeueCount); Assert.Equal(queuesConfig.MaxPollingInterval, context.MaxPollingInterval); }
public void Constructor_DefaultsValues() { QueueClient queue = new QueueClient(new Uri("https://test.queue.core.windows.net/testqueue")); QueueClient poisonQueue = new QueueClient(new Uri("https://test.queue.core.windows.net/poisonqueue")); ILoggerFactory loggerFactory = new LoggerFactory(); loggerFactory.AddProvider(new TestLoggerProvider()); QueuesOptions queuesOptions = new QueuesOptions(); QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(queue, loggerFactory, queuesOptions, poisonQueue); Assert.AreSame(queue, context.Queue); Assert.AreSame(poisonQueue, context.PoisonQueue); Assert.NotNull(context.Logger); Assert.AreEqual(queuesOptions.BatchSize, context.BatchSize); Assert.AreEqual(queuesOptions.NewBatchThreshold, context.NewBatchThreshold); Assert.AreEqual(queuesOptions.MaxDequeueCount, context.MaxDequeueCount); Assert.AreEqual(queuesOptions.MaxPollingInterval, context.MaxPollingInterval); }
public QueueProcessor Create(QueueProcessorFactoryContext context) { // demonstrates how the Queue.ServiceClient options can be configured context.Queue.ServiceClient.DefaultRequestOptions.ServerTimeout = TimeSpan.FromSeconds(30); // demonstrates how queue options can be customized context.Queue.EncodeMessage = true; if (context.Queue.Name == "initialorder") { // demonstrates how batch processing behavior can be customized // per queue (as opposed to the global settings that apply to ALL queues) context.BatchSize = 30; context.NewBatchThreshold = 100; return(new CustomQueueProcessor(context)); } // return the default processor return(new QueueProcessor(context)); }
public async Task BeginProcessingMessageAsync_MaxDequeueCountExceeded_MovesMessageToPoisonQueue() { QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(_queue, null, _queuesOptions, _poisonQueue); QueueProcessor localProcessor = new QueueProcessor(context); bool poisonMessageHandlerCalled = false; localProcessor.MessageAddedToPoisonQueue += (sender, e) => { Assert.Same(sender, localProcessor); Assert.Same(_poisonQueue, e.PoisonQueue); Assert.NotNull(e.Message); poisonMessageHandlerCalled = true; }; string messageContent = Guid.NewGuid().ToString(); CloudQueueMessage message = new CloudQueueMessage(messageContent); await _queue.AddMessageAsync(message, CancellationToken.None); CloudQueueMessage messageFromCloud = await _queue.GetMessageAsync(); for (int i = 0; i < context.MaxDequeueCount; i++) { await _queue.UpdateMessageAsync(messageFromCloud, TimeSpan.FromMilliseconds(0), MessageUpdateFields.Visibility, CancellationToken.None); messageFromCloud = await _queue.GetMessageAsync(); } Assert.Equal(6, messageFromCloud.DequeueCount); bool continueProcessing = await localProcessor.BeginProcessingMessageAsync(messageFromCloud, CancellationToken.None); Assert.False(continueProcessing); CloudQueueMessage poisonMessage = await _poisonQueue.GetMessageAsync(); Assert.NotNull(poisonMessage); Assert.Equal(messageContent, poisonMessage.AsString); Assert.True(poisonMessageHandlerCalled); }
public SharedBlobQueueListener Create() { BlobQueueTriggerExecutor triggerExecutor = new BlobQueueTriggerExecutor(_blobWrittenWatcher); // The poison queue to use for a given poison blob lives in the same // storage account as the triggering blob by default. In multi-storage account scenarios // that means that we'll be writing to different poison queues, determined by // the triggering blob. // However we use a poison queue in the host storage account as a fallback default // in case a particular blob lives in a restricted "blob only" storage account (i.e. no queues). IStorageQueue defaultPoisonQueue = _hostAccount.CreateQueueClient().GetQueueReference(HostQueueNames.BlobTriggerPoisonQueue); // this special queue bypasses the QueueProcessorFactory - we don't want people to // override this QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(_hostBlobTriggerQueue.SdkObject, _trace, _queueConfiguration, defaultPoisonQueue.SdkObject); SharedBlobQueueProcessor queueProcessor = new SharedBlobQueueProcessor(context, triggerExecutor); IListener listener = new QueueListener(_hostBlobTriggerQueue, defaultPoisonQueue, triggerExecutor, _exceptionHandler, _trace, _sharedQueueWatcher, _queueConfiguration, queueProcessor); return(new SharedBlobQueueListener(listener, triggerExecutor)); }
public async Task CompleteProcessingMessageAsync_MaxDequeueCountExceeded_MovesMessageToPoisonQueue() { QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(_queue, null, _queuesOptions, _poisonQueue); QueueProcessor localProcessor = new QueueProcessor(context); bool poisonMessageHandlerCalled = false; localProcessor.MessageAddedToPoisonQueue += (sender, e) => { Assert.Same(sender, localProcessor); Assert.Same(_poisonQueue, e.PoisonQueue); Assert.NotNull(e.Message); poisonMessageHandlerCalled = true; }; string messageContent = Guid.NewGuid().ToString(); CloudQueueMessage message = new CloudQueueMessage(messageContent); await _queue.AddMessageAsync(message, CancellationToken.None); FunctionResult result = new FunctionResult(false); for (int i = 0; i < context.MaxDequeueCount; i++) { message = await _queue.GetMessageAsync(); await localProcessor.CompleteProcessingMessageAsync(message, result, CancellationToken.None); } message = await _queue.GetMessageAsync(); Assert.Null(message); CloudQueueMessage poisonMessage = await _poisonQueue.GetMessageAsync(); Assert.NotNull(poisonMessage); Assert.Equal(messageContent, poisonMessage.AsString); Assert.True(poisonMessageHandlerCalled); }
public async Task BeginProcessingMessageAsync_MaxDequeueCountExceeded_MovesMessageToPoisonQueue() { QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(_queue, null, _queuesOptions, _poisonQueue); QueueProcessor localProcessor = new QueueProcessor(context); bool poisonMessageHandlerCalled = false; localProcessor.MessageAddedToPoisonQueue += (sender, e) => { Assert.AreSame(sender, localProcessor); Assert.AreSame(_poisonQueue, e.PoisonQueue); Assert.NotNull(e.Message); poisonMessageHandlerCalled = true; }; string messageContent = Guid.NewGuid().ToString(); await _queue.SendMessageAsync(messageContent); QueueMessage messageFromCloud = (await _queue.ReceiveMessagesAsync(1)).Value.FirstOrDefault(); for (int i = 0; i < context.MaxDequeueCount; i++) { await _queue.UpdateMessageAsync(messageFromCloud.MessageId, messageFromCloud.PopReceipt, visibilityTimeout : TimeSpan.FromMilliseconds(0)); messageFromCloud = (await _queue.ReceiveMessagesAsync(1)).Value.FirstOrDefault(); } Assert.AreEqual(6, messageFromCloud.DequeueCount); bool continueProcessing = await localProcessor.BeginProcessingMessageAsync(messageFromCloud, CancellationToken.None); Assert.False(continueProcessing); QueueMessage poisonMessage = (await _poisonQueue.ReceiveMessagesAsync(1)).Value.FirstOrDefault(); Assert.NotNull(poisonMessage); Assert.AreEqual(messageContent, poisonMessage.MessageText); Assert.True(poisonMessageHandlerCalled); }
public async Task CompleteProcessingMessageAsync_Failure_AppliesVisibilityTimeout() { var queuesOptions = new QueuesOptions { // configure a non-zero visibility timeout VisibilityTimeout = TimeSpan.FromMinutes(5) }; QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(_queue, null, queuesOptions, _poisonQueue); QueueProcessor localProcessor = new QueueProcessor(context); string messageContent = Guid.NewGuid().ToString(); CloudQueueMessage message = new CloudQueueMessage(messageContent); await _queue.AddMessageAsync(message, CancellationToken.None); var functionResult = new FunctionResult(false); message = await _queue.GetMessageAsync(); await localProcessor.CompleteProcessingMessageAsync(message, functionResult, CancellationToken.None); var delta = message.NextVisibleTime - DateTime.UtcNow; Assert.True(delta.Value.TotalMinutes > 4); }
internal static QueueProcessor CreateQueueProcessor(CloudQueue queue, CloudQueue poisonQueue, TraceWriter trace, IQueueConfiguration queueConfig, EventHandler poisonQueueMessageAddedHandler) { QueueProcessorFactoryContext context = new QueueProcessorFactoryContext(queue, trace, queueConfig, poisonQueue); QueueProcessor queueProcessor = null; if (HostQueueNames.IsHostQueue(queue.Name) && string.Compare(queue.Uri.Host, "localhost", StringComparison.OrdinalIgnoreCase) != 0) { // We only delegate to the processor factory for application queues, // not our built in control queues // We bypass this check for local testing though queueProcessor = new QueueProcessor(context); } else { queueProcessor = queueConfig.QueueProcessorFactory.Create(context); } if (poisonQueueMessageAddedHandler != null) { queueProcessor.MessageAddedToPoisonQueue += poisonQueueMessageAddedHandler; } return queueProcessor; }
public QueueProcessor Create(QueueProcessorFactoryContext context) { return(new CustomQueueProcessor(context, Configuration)); }
public SharedBlobQueueProcessor(QueueProcessorFactoryContext context, BlobQueueTriggerExecutor executor) : base(context) { _executor = executor; }
public CustomQueueProcessor(QueueProcessorFactoryContext context, IConfiguration configuration) : base(context) { Configuration = configuration; }
public CustomQueueProcessor(QueueProcessorFactoryContext context) : base(context) { Context = context; }
public void CreateQueueProcessor_CreatesProcessorCorrectly() { CloudQueue poisonQueue = null; bool poisonMessageHandlerInvoked = false; EventHandler <PoisonMessageEventArgs> poisonMessageEventHandler = (sender, e) => { poisonMessageHandlerInvoked = true; }; Mock <IQueueProcessorFactory> mockQueueProcessorFactory = new Mock <IQueueProcessorFactory>(MockBehavior.Strict); QueuesOptions queueConfig = new QueuesOptions { MaxDequeueCount = 7 }; QueueProcessor expectedQueueProcessor = null; bool processorFactoryInvoked = false; // create for a host queue - don't expect custom factory to be invoked CloudQueue queue = new CloudQueue(new Uri(string.Format("https://test.queue.core.windows.net/{0}", HostQueueNames.GetHostQueueName("12345")))); QueueProcessor queueProcessor = QueueListener.CreateQueueProcessor(queue, poisonQueue, _loggerFactory, mockQueueProcessorFactory.Object, queueConfig, poisonMessageEventHandler); Assert.False(processorFactoryInvoked); Assert.NotSame(expectedQueueProcessor, queueProcessor); queueProcessor.OnMessageAddedToPoisonQueue(new PoisonMessageEventArgs(null, poisonQueue)); Assert.True(poisonMessageHandlerInvoked); QueueProcessorFactoryContext processorFactoryContext = null; mockQueueProcessorFactory.Setup(p => p.Create(It.IsAny <QueueProcessorFactoryContext>())) .Callback <QueueProcessorFactoryContext>((mockProcessorContext) => { processorFactoryInvoked = true; Assert.Same(queue, mockProcessorContext.Queue); Assert.Same(poisonQueue, mockProcessorContext.PoisonQueue); Assert.Equal(queueConfig.MaxDequeueCount, mockProcessorContext.MaxDequeueCount); Assert.NotNull(mockProcessorContext.Logger); processorFactoryContext = mockProcessorContext; }) .Returns(() => { expectedQueueProcessor = new QueueProcessor(processorFactoryContext); return(expectedQueueProcessor); }); // when storage host is "localhost" we invoke the processor factory even for // host queues (this enables local test mocking) processorFactoryInvoked = false; queue = new CloudQueue(new Uri(string.Format("https://localhost/{0}", HostQueueNames.GetHostQueueName("12345")))); queueProcessor = QueueListener.CreateQueueProcessor(queue, poisonQueue, _loggerFactory, mockQueueProcessorFactory.Object, queueConfig, poisonMessageEventHandler); Assert.True(processorFactoryInvoked); Assert.Same(expectedQueueProcessor, queueProcessor); // create for application queue - expect processor factory to be invoked poisonMessageHandlerInvoked = false; processorFactoryInvoked = false; queue = new CloudQueue(new Uri("https://test.queue.core.windows.net/testqueue")); queueProcessor = QueueListener.CreateQueueProcessor(queue, poisonQueue, _loggerFactory, mockQueueProcessorFactory.Object, queueConfig, poisonMessageEventHandler); Assert.True(processorFactoryInvoked); Assert.Same(expectedQueueProcessor, queueProcessor); queueProcessor.OnMessageAddedToPoisonQueue(new PoisonMessageEventArgs(null, poisonQueue)); Assert.True(poisonMessageHandlerInvoked); // if poison message watcher not specified, event not subscribed to poisonMessageHandlerInvoked = false; processorFactoryInvoked = false; queueProcessor = QueueListener.CreateQueueProcessor(queue, poisonQueue, _loggerFactory, mockQueueProcessorFactory.Object, queueConfig, null); Assert.True(processorFactoryInvoked); Assert.Same(expectedQueueProcessor, queueProcessor); queueProcessor.OnMessageAddedToPoisonQueue(new PoisonMessageEventArgs(null, poisonQueue)); Assert.False(poisonMessageHandlerInvoked); }
public override QueueProcessor Create(QueueProcessorFactoryContext context) { return(new FakeQueueProcessor(context, _storageAccount)); }
public CustomQueueProcessor(QueueProcessorFactoryContext context) : base(context) { MaxDequeueCount = 12; }
public QueueProcessor Create(QueueProcessorFactoryContext context) { context = new QueueProcessorFactoryContext(_queue, _loggerFactory, _options, _poisonQueue); return(new SharedBlobQueueProcessor(context, _triggerExecutor)); }
public TestQueueProcessor(QueueProcessorFactoryContext context) : base(context) { }
public QueueProcessor Create(QueueProcessorFactoryContext context) { return(new TestQueueProcessor(context)); }