There is an API that accepts an entity with a previously unknown ID. I need to configure the rate limiter so that entities with the same ID get into the queue. I figured out how to create a window and a queue. How to make a separate queue for each ID?
The entity is a JSON file. The ID is inside the file.
The following is written, but this forms one queue:
services.AddRateLimiter(options => options
.AddFixedWindowLimiter(policyName: "UserPolicy", options =>
{
options.PermitLimit = 1;
options.Window = TimeSpan.FromSeconds(10);
options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
options.QueueLimit = 3;
}));
You can try using PartitionedRateLimiter
. Something along these lines (not tested):
builder.Services.AddRateLimiter(options =>
{
options.AddPolicy("myRateLimiter1", context =>
{
var request = context.Request;
var partitionKey = "";
if (request.Method == HttpMethods.Post && request.ContentLength > 0)
{
request.EnableBuffering();
var buffer = new byte[Convert.ToInt32(request.ContentLength)];
request.Body.Read(buffer, 0, buffer.Length);
//get body string here...
var requestContent = Encoding.UTF8.GetString(buffer);
// get partition key here... partitionKey = ...
request.Body.Position = 0; //rewinding the stream to 0
}
return RateLimitPartition.GetFixedWindowLimiter(
partitionKey: partitionKey,
factory: partition => new FixedWindowRateLimiterOptions
{
PermitLimit = 1,
Window = TimeSpan.FromSeconds(10),
QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
QueueLimit = 3
});
});
});
Though I would suggest to consider passing Id in some other way (headers) or resolve the limiter on the handler/BL level.