This is my bulkhead policy:
BulkheadPolicy = Policy
.BulkheadAsync(maxParallelization: 2,
maxQueuingActions: 2, onBulkheadRejectedAsync: (context) =>
{
Console.WriteLine("Rejected");
return Task.CompletedTask;
});
It should allow only 4 concurrent tasks to execute/wait for execution.
However, I end up getting 6 tasks being able to run through the bulkhead policy.
This is my controller action:
[HttpGet("bulkhead")]
public async Task<object> Bulkhead()
{
Console.WriteLine(DateTime.UtcNow);
var bhCount = _policyManager.BulkheadPolicy.BulkheadAvailableCount;
var queueCount = _policyManager.BulkheadPolicy.QueueAvailableCount;
// The policy is used here
await _policyManager.BulkheadPolicy.ExecuteAsync(async (context) =>
{
await Task.Delay(10000);
}, new Context());
return new
{
bhCount,
queueCount
};
}
In my browser, I used this script to simulate 14 concurrent tasks:
for (var i = 0; i < 14; i++) {
fetch('https://localhost:44313/api/Bulkheads/bulkhead')
.then(result=>console.log(result));
}
which should produce only 4 200OK
responses. However, I end up getting 6 200OK
responses.
I ran the test many times and got the same result. Does anybody have an idea why since the same behavior works well with a console application? Did I miss something here? Many thanks.
UPDATE 1:
This is my IPolicyManager
interface
public interface IPolicyManager
{
AsyncBulkheadPolicy BulkheadPolicy { get; }
}
public class PolicyManager : IPolicyManager
{
public PolicyManager()
{
Init();
}
public AsyncBulkheadPolicy BulkheadPolicy { get; private set; }
private void Init()
{
BulkheadPolicy = Policy
.BulkheadAsync(maxParallelization: 2,
maxQueuingActions: 2, onBulkheadRejectedAsync: (context) =>
{
Console.WriteLine("Rejected");
return Task.CompletedTask;
});
}
}
UPDATE 2: When I send a fixed request (fixed URL), it failed quite slow, but when I append a random argument in the requests, the result is as expected (fail fast and only 4 requests can proceed).
for (var i = 0; i < 14; i++) {
fetch('https://localhost:44313/api/Bulkheads/bulkhead?count=' + i)
.then(result=>console.log(result));
}
It turned out that the browser's behavior was not as expected. I wrote a console application that does the same task and it works well: fail fast and only 4 requests can proceed at a time. So I can confirm this is not an issue from Polly or ASP.NET Core. Maybe it relates to caching mechanism of web browser (I'm using Edge): https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching