diff --git a/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/CHANGELOG.md b/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/CHANGELOG.md
index 4e7b415c4be08..c2bf2d667debd 100644
--- a/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/CHANGELOG.md
+++ b/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/CHANGELOG.md
@@ -3,6 +3,7 @@
## 5.2.0-beta.1 (Unreleased)
### Features Added
+- Added support for `BlobsOptions.MaxDequeueCount`
### Breaking Changes
diff --git a/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/api/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs.netstandard2.0.cs b/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/api/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs.netstandard2.0.cs
index 72b2f32ce4da4..c50e94cfa16a9 100644
--- a/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/api/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs.netstandard2.0.cs
+++ b/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/api/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs.netstandard2.0.cs
@@ -44,6 +44,7 @@ public partial class BlobsOptions : Microsoft.Azure.WebJobs.Hosting.IOptionsForm
{
public BlobsOptions() { }
public int MaxDegreeOfParallelism { get { throw null; } set { } }
+ public int MaxDequeueCount { get { throw null; } set { } }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
string Microsoft.Azure.WebJobs.Hosting.IOptionsFormatter.Format() { throw null; }
}
diff --git a/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/samples/functionapp/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs.Samples.Function.App.csproj b/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/samples/functionapp/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs.Samples.Function.App.csproj
index 9cdebf27d6d1d..80128b5c71674 100644
--- a/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/samples/functionapp/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs.Samples.Function.App.csproj
+++ b/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/samples/functionapp/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs.Samples.Function.App.csproj
@@ -8,7 +8,8 @@
-
+
+
diff --git a/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/src/Config/BlobsOptions.cs b/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/src/Config/BlobsOptions.cs
index 938c6b3c8b668..9aacfa444ed7a 100644
--- a/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/src/Config/BlobsOptions.cs
+++ b/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/src/Config/BlobsOptions.cs
@@ -15,7 +15,10 @@ namespace Microsoft.Azure.WebJobs.Host
///
public class BlobsOptions : IOptionsFormatter
{
+ private const int DefaultMaxDequeueCount = 5;
+
private int _maxDegreeOfParallelism;
+ private int _maxDequeueCount = DefaultMaxDequeueCount;
///
/// Constructs a new instance.
@@ -43,6 +46,30 @@ public int MaxDegreeOfParallelism
}
}
+ ///
+ /// Gets or sets the number of times to try processing a message before moving it to the poison queue (where
+ /// possible).
+ ///
+ ///
+ /// Some queues do not have corresponding poison queues, and this property does not apply to them. Specifically,
+ /// there are no corresponding poison queues for any queue whose name already ends in "-poison" or any queue
+ /// whose name is already too long to add a "-poison" suffix.
+ ///
+ public int MaxDequeueCount
+ {
+ get { return _maxDequeueCount; }
+
+ set
+ {
+ if (value < 1)
+ {
+ throw new ArgumentException("MaxDequeueCount must not be less than 1.", nameof(value));
+ }
+
+ _maxDequeueCount = value;
+ }
+ }
+
///
[EditorBrowsable(EditorBrowsableState.Never)]
string IOptionsFormatter.Format()
diff --git a/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/src/Listeners/SharedBlobQueueListenerFactory.cs b/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/src/Listeners/SharedBlobQueueListenerFactory.cs
index b3a09ca0c2430..1355ce98b6894 100644
--- a/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/src/Listeners/SharedBlobQueueListenerFactory.cs
+++ b/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/src/Listeners/SharedBlobQueueListenerFactory.cs
@@ -98,6 +98,7 @@ internal static QueuesOptions BlobsOptionsToQueuesOptions(BlobsOptions blobsOpti
{
BatchSize = batchSize,
NewBatchThreshold = newBatchThreshold,
+ MaxDequeueCount = blobsOptions.MaxDequeueCount
};
}
diff --git a/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/tests/Listeners/SharedBlobQueueListenerFactoryTests.cs b/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/tests/Listeners/SharedBlobQueueListenerFactoryTests.cs
index 7d906ddf4ebe0..52225008e38fa 100644
--- a/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/tests/Listeners/SharedBlobQueueListenerFactoryTests.cs
+++ b/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/tests/Listeners/SharedBlobQueueListenerFactoryTests.cs
@@ -8,20 +8,21 @@ namespace Microsoft.Azure.WebJobs.Extensions.Storage.Blobs.Listeners
{
public class SharedBlobQueueListenerFactoryTests
{
- [TestCase(100, 32, 68)]
- [TestCase(64, 32, 32)]
- [TestCase(63, 32, 31)]
- [TestCase(62, 32, 30)]
- [TestCase(16, 9, 7)]
- [TestCase(3, 2, 1)]
- [TestCase(2, 2, 0)]
- [TestCase(1, 1, 0)]
- public void ConvertsBlobOptionsToQueueOptionsCorrectly(int maxDegreeOfParallelism, int expectedBatchSize, int expectedNewBatchThreshold)
+ [TestCase(100, 32, 68, 6)]
+ [TestCase(64, 32, 32, 5)]
+ [TestCase(63, 32, 31, 4)]
+ [TestCase(62, 32, 30, 4)]
+ [TestCase(16, 9, 7, 3)]
+ [TestCase(3, 2, 1, 1)]
+ [TestCase(2, 2, 0, 1)]
+ [TestCase(1, 1, 0, 1)]
+ public void ConvertsBlobOptionsToQueueOptionsCorrectly(int maxDegreeOfParallelism, int expectedBatchSize, int expectedNewBatchThreshold, int maxDequeueCount)
{
// Arrange
var blobOptions = new BlobsOptions()
{
MaxDegreeOfParallelism = maxDegreeOfParallelism,
+ MaxDequeueCount = maxDequeueCount,
};
// Act
@@ -30,6 +31,7 @@ public void ConvertsBlobOptionsToQueueOptionsCorrectly(int maxDegreeOfParallelis
// Assert
Assert.AreEqual(expectedBatchSize, queueOptions.BatchSize);
Assert.AreEqual(expectedNewBatchThreshold, queueOptions.NewBatchThreshold);
+ Assert.AreEqual(maxDequeueCount, queueOptions.MaxDequeueCount);
}
}
}
diff --git a/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/tests/StorageBlobsWebJobsBuilderExtensionsTests.cs b/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/tests/StorageBlobsWebJobsBuilderExtensionsTests.cs
index 6e4ce20aed80b..c5c9b56ab4f3c 100644
--- a/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/tests/StorageBlobsWebJobsBuilderExtensionsTests.cs
+++ b/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/tests/StorageBlobsWebJobsBuilderExtensionsTests.cs
@@ -18,6 +18,7 @@ public void ConfigureOptions_AppliesValuesCorrectly_Blobs()
var values = new Dictionary
{
{ $"{extensionPath}:MaxDegreeOfParallelism", "2" },
+ { $"{extensionPath}:MaxDequeueCount", "3" },
};
BlobsOptions options = TestHelpers.GetConfiguredOptions(b =>
@@ -26,6 +27,7 @@ public void ConfigureOptions_AppliesValuesCorrectly_Blobs()
}, values);
Assert.AreEqual(2, options.MaxDegreeOfParallelism);
+ Assert.AreEqual(3, options.MaxDequeueCount);
}
}
}
diff --git a/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Queues/samples/functionapp/Microsoft.Azure.WebJobs.Extensions.Storage.Queues.Samples.Function.App.csproj b/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Queues/samples/functionapp/Microsoft.Azure.WebJobs.Extensions.Storage.Queues.Samples.Function.App.csproj
index b9ef0b1b295a5..3fee0cdb92609 100644
--- a/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Queues/samples/functionapp/Microsoft.Azure.WebJobs.Extensions.Storage.Queues.Samples.Function.App.csproj
+++ b/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Queues/samples/functionapp/Microsoft.Azure.WebJobs.Extensions.Storage.Queues.Samples.Function.App.csproj
@@ -8,6 +8,7 @@
+