Pradeep
Pradeep

Reputation: 71

How to create a Semaphoreslim instance on application startup and use the same instance across all the requests?

I have a scenario where I have to limit the number of parallel 3rd party API calls to 200 at a time. For this I have used SemaphoreSlim and restricted the number of threads that can execute the code block to 200.

This works fine for a single user/request. But what if multiple requests come at the same time?

Will the block of code between the SemaphoreSlim wait and release be allowed for only 200 threads at any point of time/any no. of requests or will it allow 200 threads per request?

If it is by request then how can I create a SemaphoreSlim instance on application startup so that I can use the same instance for all the requests?

Upvotes: 0

Views: 500

Answers (2)

Zinov
Zinov

Reputation: 4119

If you want to limit your request. Asp.net core has a rate limit implementation that can go at the level of the IPs or at the level of the resources. It will depend on how you want to configure it. This will prevent malicious attacks on your web application/api resources

Basically you need to install this package

dotnet add package AspNetCoreRateLimit

On your ConfigureServices you can do

services.RegisterLimitAndThrottlingMvcConfiguration();

This is the implementation of the extension method

private static IServiceCollection RegisterLimitAndThrottlingMvcConfiguration(this IServiceCollection container,
            ServiceLifetime lifeTime = ServiceLifetime.Scoped)
        {
            //rate limiting
            //to store the counters and rules in memory
            container.AddMemoryCache();

            //configuring the options
            container.Configure<IpRateLimitOptions>(options =>
            {
                options.GeneralRules = new List<RateLimitRule>
                {
                    //any resource limit 1000 request every 5 min
                    new RateLimitRule
                    {
                        Endpoint = "*",
                        Limit = 1000,
                        Period = "5m"
                    },
                    //200 request every 10 seconds
                    new RateLimitRule()
                    {
                        Endpoint = "*",
                        Limit = 200,
                        Period = "10s"
                    }
                };
            });

            container.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
            container.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();

            return container;
        }

And set the middleware on Configure method

//for limiting(header -> X-Rate-Limit- Limit, X-Rate-Limit-Remaining, X-Rate-Limit-Reset
app.UseIpRateLimiting();

For limiting you can find a good article on this link limiting

Upvotes: 2

Paweł Okrasa
Paweł Okrasa

Reputation: 90

I don't think creating global semaphore and interfering that way into how ASP.NET will manage thread pool will be good.

After quick search i found this page on how to limit concurrent connections but I am not familiar with it soo it is just a guess: https://www.oreilly.com/library/view/mastering-aspnet-core/9781787283688/f460937d-fa5e-439b-afa8-d0a417abc1ea.xhtml

it is single line addition in Program.cs: enter image description here

Upvotes: 0

Related Questions