From 1b2a24eadbf88e2e01a6fc1287be07c45044a6ea Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 14 Oct 2025 01:49:58 +0000
Subject: [PATCH 1/2] Initial plan
From c92cd28eafd1a0f0333ed8ec7271a910428ae319 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 14 Oct 2025 01:58:27 +0000
Subject: [PATCH 2/2] Delete ConcurrencyLimiter middleware and remove all
references
Co-authored-by: BrennanConroy <7574801+BrennanConroy@users.noreply.github.com>
---
AspNetCore.slnx | 8 -
eng/Baseline.Designer.props | 9 -
eng/Baseline.xml | 1 -
eng/ProjectReferences.props | 1 -
eng/ShippingAssemblies.props | 1 -
.../ConcurrencyLimiter.slnf | 28 ---
.../perf/Microbenchmarks/AssemblyInfo.cs | 4 -
....ConcurrencyLimiter.Microbenchmarks.csproj | 19 --
.../Microbenchmarks/QueueEmptyOverhead.cs | 75 ------
.../perf/Microbenchmarks/QueueFullOverhead.cs | 87 -------
.../QueueRequestsOverwritten.cs | 95 -------
.../sample/ConcurrencyLimiterSample.csproj | 12 -
.../sample/Properties/launchSettings.json | 27 --
.../ConcurrencyLimiter/sample/Startup.cs | 42 ----
.../src/ConcurrencyLimiterEventSource.cs | 107 --------
.../src/ConcurrencyLimiterExtensions.cs | 25 --
.../src/ConcurrencyLimiterMiddleware.cs | 100 --------
.../src/ConcurrencyLimiterOptions.cs | 22 --
...osoft.AspNetCore.ConcurrencyLimiter.csproj | 23 --
.../src/PublicAPI.Shipped.txt | 22 --
.../src/PublicAPI.Unshipped.txt | 1 -
.../src/QueuePolicies/BasePolicy.cs | 98 --------
.../src/QueuePolicies/IQueuePolicy.cs | 23 --
.../src/QueuePolicies/QueuePolicy.cs | 15 --
.../src/QueuePolicies/QueuePolicyOptions.cs | 22 --
.../QueuePolicyServiceCollectionExtensions.cs | 40 ---
.../src/QueuePolicies/StackPolicy.cs | 15 --
.../ConcurrencyLimiterEventSourceTests.cs | 137 ----------
...AspNetCore.ConcurrencyLimiter.Tests.csproj | 18 --
.../test/MiddlewareTests.cs | 237 ------------------
.../test/PolicyTests/QueuePolicyTests.cs | 70 ------
.../test/PolicyTests/StackPolicyTests.cs | 151 -----------
.../ConcurrencyLimiter/test/TaskExtensions.cs | 35 ---
.../ConcurrencyLimiter/test/TestUtils.cs | 114 ---------
src/Middleware/Middleware.slnf | 4 -
src/Tools/Tools.slnf | 1 -
36 files changed, 1689 deletions(-)
delete mode 100644 src/Middleware/ConcurrencyLimiter/ConcurrencyLimiter.slnf
delete mode 100644 src/Middleware/ConcurrencyLimiter/perf/Microbenchmarks/AssemblyInfo.cs
delete mode 100644 src/Middleware/ConcurrencyLimiter/perf/Microbenchmarks/Microsoft.AspNetCore.ConcurrencyLimiter.Microbenchmarks.csproj
delete mode 100644 src/Middleware/ConcurrencyLimiter/perf/Microbenchmarks/QueueEmptyOverhead.cs
delete mode 100644 src/Middleware/ConcurrencyLimiter/perf/Microbenchmarks/QueueFullOverhead.cs
delete mode 100644 src/Middleware/ConcurrencyLimiter/perf/Microbenchmarks/QueueRequestsOverwritten.cs
delete mode 100644 src/Middleware/ConcurrencyLimiter/sample/ConcurrencyLimiterSample.csproj
delete mode 100644 src/Middleware/ConcurrencyLimiter/sample/Properties/launchSettings.json
delete mode 100644 src/Middleware/ConcurrencyLimiter/sample/Startup.cs
delete mode 100644 src/Middleware/ConcurrencyLimiter/src/ConcurrencyLimiterEventSource.cs
delete mode 100644 src/Middleware/ConcurrencyLimiter/src/ConcurrencyLimiterExtensions.cs
delete mode 100644 src/Middleware/ConcurrencyLimiter/src/ConcurrencyLimiterMiddleware.cs
delete mode 100644 src/Middleware/ConcurrencyLimiter/src/ConcurrencyLimiterOptions.cs
delete mode 100644 src/Middleware/ConcurrencyLimiter/src/Microsoft.AspNetCore.ConcurrencyLimiter.csproj
delete mode 100644 src/Middleware/ConcurrencyLimiter/src/PublicAPI.Shipped.txt
delete mode 100644 src/Middleware/ConcurrencyLimiter/src/PublicAPI.Unshipped.txt
delete mode 100644 src/Middleware/ConcurrencyLimiter/src/QueuePolicies/BasePolicy.cs
delete mode 100644 src/Middleware/ConcurrencyLimiter/src/QueuePolicies/IQueuePolicy.cs
delete mode 100644 src/Middleware/ConcurrencyLimiter/src/QueuePolicies/QueuePolicy.cs
delete mode 100644 src/Middleware/ConcurrencyLimiter/src/QueuePolicies/QueuePolicyOptions.cs
delete mode 100644 src/Middleware/ConcurrencyLimiter/src/QueuePolicies/QueuePolicyServiceCollectionExtensions.cs
delete mode 100644 src/Middleware/ConcurrencyLimiter/src/QueuePolicies/StackPolicy.cs
delete mode 100644 src/Middleware/ConcurrencyLimiter/test/ConcurrencyLimiterEventSourceTests.cs
delete mode 100644 src/Middleware/ConcurrencyLimiter/test/Microsoft.AspNetCore.ConcurrencyLimiter.Tests.csproj
delete mode 100644 src/Middleware/ConcurrencyLimiter/test/MiddlewareTests.cs
delete mode 100644 src/Middleware/ConcurrencyLimiter/test/PolicyTests/QueuePolicyTests.cs
delete mode 100644 src/Middleware/ConcurrencyLimiter/test/PolicyTests/StackPolicyTests.cs
delete mode 100644 src/Middleware/ConcurrencyLimiter/test/TaskExtensions.cs
delete mode 100644 src/Middleware/ConcurrencyLimiter/test/TestUtils.cs
diff --git a/AspNetCore.slnx b/AspNetCore.slnx
index 60f5ca0d74fc..6382f5d163cb 100644
--- a/AspNetCore.slnx
+++ b/AspNetCore.slnx
@@ -469,14 +469,6 @@
-
-
-
-
-
-
-
-
diff --git a/eng/Baseline.Designer.props b/eng/Baseline.Designer.props
index f566358b9acb..ad74465dc235 100644
--- a/eng/Baseline.Designer.props
+++ b/eng/Baseline.Designer.props
@@ -256,15 +256,6 @@
-
-
- 9.0.0
-
-
-
-
-
-
9.0.0
diff --git a/eng/Baseline.xml b/eng/Baseline.xml
index 1b4ce55e8e33..bf3cd9b3ab99 100644
--- a/eng/Baseline.xml
+++ b/eng/Baseline.xml
@@ -46,7 +46,6 @@ Update this list when preparing for a new patch.
-
diff --git a/eng/ProjectReferences.props b/eng/ProjectReferences.props
index 4dcee4af652b..461c89f299b8 100644
--- a/eng/ProjectReferences.props
+++ b/eng/ProjectReferences.props
@@ -77,7 +77,6 @@
-
diff --git a/eng/ShippingAssemblies.props b/eng/ShippingAssemblies.props
index 0acec8474d50..6b969841ea81 100644
--- a/eng/ShippingAssemblies.props
+++ b/eng/ShippingAssemblies.props
@@ -132,7 +132,6 @@
-
diff --git a/src/Middleware/ConcurrencyLimiter/ConcurrencyLimiter.slnf b/src/Middleware/ConcurrencyLimiter/ConcurrencyLimiter.slnf
deleted file mode 100644
index 7d62ecbf1aea..000000000000
--- a/src/Middleware/ConcurrencyLimiter/ConcurrencyLimiter.slnf
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "solution": {
- "path": "..\\..\\..\\AspNetCore.slnx",
- "projects": [
- "src\\Hosting\\Abstractions\\src\\Microsoft.AspNetCore.Hosting.Abstractions.csproj",
- "src\\Hosting\\Hosting\\src\\Microsoft.AspNetCore.Hosting.csproj",
- "src\\Hosting\\Server.Abstractions\\src\\Microsoft.AspNetCore.Hosting.Server.Abstractions.csproj",
- "src\\Http\\Http.Abstractions\\src\\Microsoft.AspNetCore.Http.Abstractions.csproj",
- "src\\Http\\Http.Extensions\\src\\Microsoft.AspNetCore.Http.Extensions.csproj",
- "src\\Extensions\\Features\\src\\Microsoft.Extensions.Features.csproj",
- "src\\Http\\Http.Features\\src\\Microsoft.AspNetCore.Http.Features.csproj",
- "src\\Http\\WebUtilities\\src\\Microsoft.AspNetCore.WebUtilities.csproj",
- "src\\Servers\\Connections.Abstractions\\src\\Microsoft.AspNetCore.Connections.Abstractions.csproj",
- "src\\Servers\\Kestrel\\Core\\src\\Microsoft.AspNetCore.Server.Kestrel.Core.csproj",
- "src\\Servers\\Kestrel\\Kestrel\\src\\Microsoft.AspNetCore.Server.Kestrel.csproj",
- "src\\Servers\\Kestrel\\Transport.NamedPipes\\src\\Microsoft.AspNetCore.Server.Kestrel.Transport.NamedPipes.csproj",
- "src\\Servers\\Kestrel\\Transport.Quic\\src\\Microsoft.AspNetCore.Server.Kestrel.Transport.Quic.csproj",
- "src\\Servers\\Kestrel\\Transport.Sockets\\src\\Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.csproj",
- "src\\Http\\Headers\\src\\Microsoft.Net.Http.Headers.csproj",
- "src\\Http\\Http\\src\\Microsoft.AspNetCore.Http.csproj",
- "src\\Middleware\\ConcurrencyLimiter\\perf\\Microbenchmarks\\Microsoft.AspNetCore.ConcurrencyLimiter.Microbenchmarks.csproj",
- "src\\Middleware\\ConcurrencyLimiter\\sample\\ConcurrencyLimiterSample.csproj",
- "src\\Middleware\\ConcurrencyLimiter\\src\\Microsoft.AspNetCore.ConcurrencyLimiter.csproj",
- "src\\Middleware\\ConcurrencyLimiter\\test\\Microsoft.AspNetCore.ConcurrencyLimiter.Tests.csproj",
- "src\\Middleware\\HttpsPolicy\\src\\Microsoft.AspNetCore.HttpsPolicy.csproj"
- ]
- }
-}
diff --git a/src/Middleware/ConcurrencyLimiter/perf/Microbenchmarks/AssemblyInfo.cs b/src/Middleware/ConcurrencyLimiter/perf/Microbenchmarks/AssemblyInfo.cs
deleted file mode 100644
index 09f49228e9e6..000000000000
--- a/src/Middleware/ConcurrencyLimiter/perf/Microbenchmarks/AssemblyInfo.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-[assembly: BenchmarkDotNet.Attributes.AspNetCoreBenchmark]
diff --git a/src/Middleware/ConcurrencyLimiter/perf/Microbenchmarks/Microsoft.AspNetCore.ConcurrencyLimiter.Microbenchmarks.csproj b/src/Middleware/ConcurrencyLimiter/perf/Microbenchmarks/Microsoft.AspNetCore.ConcurrencyLimiter.Microbenchmarks.csproj
deleted file mode 100644
index 2674be405d14..000000000000
--- a/src/Middleware/ConcurrencyLimiter/perf/Microbenchmarks/Microsoft.AspNetCore.ConcurrencyLimiter.Microbenchmarks.csproj
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
- Exe
- $(DefaultNetCoreTargetFramework)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Middleware/ConcurrencyLimiter/perf/Microbenchmarks/QueueEmptyOverhead.cs b/src/Middleware/ConcurrencyLimiter/perf/Microbenchmarks/QueueEmptyOverhead.cs
deleted file mode 100644
index 1ab18f60558a..000000000000
--- a/src/Middleware/ConcurrencyLimiter/perf/Microbenchmarks/QueueEmptyOverhead.cs
+++ /dev/null
@@ -1,75 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using BenchmarkDotNet.Attributes;
-using Microsoft.AspNetCore.ConcurrencyLimiter.Tests;
-using Microsoft.AspNetCore.Http;
-
-namespace Microsoft.AspNetCore.ConcurrencyLimiter.Microbenchmarks;
-
-public class QueueEmptyOverhead
-{
- private const int _numRequests = 20000;
-
-#pragma warning disable CS0618 // Type or member is obsolete
- private ConcurrencyLimiterMiddleware _middlewareQueue;
- private ConcurrencyLimiterMiddleware _middlewareStack;
-#pragma warning restore CS0618 // Type or member is obsolete
- private RequestDelegate _restOfServer;
-
- [GlobalSetup]
- public void GlobalSetup()
- {
- _restOfServer = YieldsThreadInternally ? (RequestDelegate)YieldsThread : (RequestDelegate)CompletesImmediately;
-
- _middlewareQueue = TestUtils.CreateTestMiddleware_QueuePolicy(
- maxConcurrentRequests: 1,
- requestQueueLimit: 100,
- next: _restOfServer);
-
- _middlewareStack = TestUtils.CreateTestMiddleware_StackPolicy(
- maxConcurrentRequests: 1,
- requestQueueLimit: 100,
- next: _restOfServer);
- }
-
- [Params(false, true)]
- public bool YieldsThreadInternally;
-
- [Benchmark(OperationsPerInvoke = _numRequests)]
- public async Task Baseline()
- {
- for (int i = 0; i < _numRequests; i++)
- {
- await _restOfServer(null);
- }
- }
-
- [Benchmark(OperationsPerInvoke = _numRequests)]
- public async Task WithEmptyQueueOverhead_QueuePolicy()
- {
- for (int i = 0; i < _numRequests; i++)
- {
- await _middlewareQueue.Invoke(null);
- }
- }
-
- [Benchmark(OperationsPerInvoke = _numRequests)]
- public async Task WithEmptyQueueOverhead_StackPolicy()
- {
- for (int i = 0; i < _numRequests; i++)
- {
- await _middlewareStack.Invoke(null);
- }
- }
-
- private static async Task YieldsThread(HttpContext context)
- {
- await Task.Yield();
- }
-
- private static Task CompletesImmediately(HttpContext context)
- {
- return Task.CompletedTask;
- }
-}
diff --git a/src/Middleware/ConcurrencyLimiter/perf/Microbenchmarks/QueueFullOverhead.cs b/src/Middleware/ConcurrencyLimiter/perf/Microbenchmarks/QueueFullOverhead.cs
deleted file mode 100644
index 22afdb9bf538..000000000000
--- a/src/Middleware/ConcurrencyLimiter/perf/Microbenchmarks/QueueFullOverhead.cs
+++ /dev/null
@@ -1,87 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using BenchmarkDotNet.Attributes;
-using Microsoft.AspNetCore.ConcurrencyLimiter.Tests;
-using Microsoft.AspNetCore.Http;
-
-namespace Microsoft.AspNetCore.ConcurrencyLimiter.Microbenchmarks;
-
-public class QueueFullOverhead
-{
- private const int _numRequests = 2000;
- private int _requestCount = 0;
- private readonly ManualResetEventSlim _mres = new ManualResetEventSlim();
-
-#pragma warning disable CS0618 // Type or member is obsolete
- private ConcurrencyLimiterMiddleware _middlewareQueue;
- private ConcurrencyLimiterMiddleware _middlewareStack;
-#pragma warning restore CS0618 // Type or member is obsolete
-
- [Params(8)]
- public int MaxConcurrentRequests;
-
- [GlobalSetup]
- public void GlobalSetup()
- {
- _middlewareQueue = TestUtils.CreateTestMiddleware_QueuePolicy(
- maxConcurrentRequests: MaxConcurrentRequests,
- requestQueueLimit: _numRequests,
- next: IncrementAndCheck);
-
- _middlewareStack = TestUtils.CreateTestMiddleware_StackPolicy(
- maxConcurrentRequests: MaxConcurrentRequests,
- requestQueueLimit: _numRequests,
- next: IncrementAndCheck);
- }
-
- [IterationSetup]
- public void Setup()
- {
- _requestCount = 0;
- _mres.Reset();
- }
-
- private async Task IncrementAndCheck(HttpContext context)
- {
- if (Interlocked.Increment(ref _requestCount) == _numRequests)
- {
- _mres.Set();
- }
-
- await Task.Yield();
- }
-
- [Benchmark(OperationsPerInvoke = _numRequests)]
- public void Baseline()
- {
- for (int i = 0; i < _numRequests; i++)
- {
- _ = IncrementAndCheck(null);
- }
-
- _mres.Wait();
- }
-
- [Benchmark(OperationsPerInvoke = _numRequests)]
- public void QueueingAll_QueuePolicy()
- {
- for (int i = 0; i < _numRequests; i++)
- {
- _ = _middlewareStack.Invoke(null);
- }
-
- _mres.Wait();
- }
-
- [Benchmark(OperationsPerInvoke = _numRequests)]
- public void QueueingAll_StackPolicy()
- {
- for (int i = 0; i < _numRequests; i++)
- {
- _ = _middlewareQueue.Invoke(null);
- }
-
- _mres.Wait();
- }
-}
diff --git a/src/Middleware/ConcurrencyLimiter/perf/Microbenchmarks/QueueRequestsOverwritten.cs b/src/Middleware/ConcurrencyLimiter/perf/Microbenchmarks/QueueRequestsOverwritten.cs
deleted file mode 100644
index 3954ce92e512..000000000000
--- a/src/Middleware/ConcurrencyLimiter/perf/Microbenchmarks/QueueRequestsOverwritten.cs
+++ /dev/null
@@ -1,95 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using BenchmarkDotNet.Attributes;
-using Microsoft.AspNetCore.ConcurrencyLimiter.Tests;
-using Microsoft.AspNetCore.Http;
-
-namespace Microsoft.AspNetCore.ConcurrencyLimiter.Microbenchmarks;
-
-public class QueueRequestsOverwritten
-{
- private const int _numRejects = 5000;
- private readonly int _queueLength = 20;
- private int _rejectionCount = 0;
- private readonly ManualResetEventSlim _mres = new ManualResetEventSlim();
-
-#pragma warning disable CS0618 // Type or member is obsolete
- private ConcurrencyLimiterMiddleware _middlewareQueue;
- private ConcurrencyLimiterMiddleware _middlewareStack;
-#pragma warning restore CS0618 // Type or member is obsolete
-
- [GlobalSetup]
- public void GlobalSetup()
- {
- _middlewareQueue = TestUtils.CreateTestMiddleware_QueuePolicy(
- maxConcurrentRequests: 1,
- requestQueueLimit: 20,
- next: WaitForever,
- onRejected: IncrementRejections);
-
- _middlewareStack = TestUtils.CreateTestMiddleware_StackPolicy(
- maxConcurrentRequests: 1,
- requestQueueLimit: 20,
- next: WaitForever,
- onRejected: IncrementRejections);
- }
-
- [IterationSetup]
- public void Setup()
- {
- _rejectionCount = 0;
- _mres.Reset();
- }
-
- private async Task IncrementRejections(HttpContext context)
- {
- if (Interlocked.Increment(ref _rejectionCount) == _numRejects)
- {
- _mres.Set();
- }
-
- await Task.Yield();
- }
-
- private async Task WaitForever(HttpContext context)
- {
- await Task.Delay(int.MaxValue);
- }
-
- [Benchmark(OperationsPerInvoke = _numRejects)]
- public void Baseline()
- {
- var toSend = _queueLength + _numRejects + 1;
- for (int i = 0; i < toSend; i++)
- {
- _ = IncrementRejections(new DefaultHttpContext());
- }
-
- _mres.Wait();
- }
-
- [Benchmark(OperationsPerInvoke = _numRejects)]
- public void RejectingRapidly_QueuePolicy()
- {
- var toSend = _queueLength + _numRejects + 1;
- for (int i = 0; i < toSend; i++)
- {
- _ = _middlewareQueue.Invoke(new DefaultHttpContext());
- }
-
- _mres.Wait();
- }
-
- [Benchmark(OperationsPerInvoke = _numRejects)]
- public void RejectingRapidly_StackPolicy()
- {
- var toSend = _queueLength + _numRejects + 1;
- for (int i = 0; i < toSend; i++)
- {
- _ = _middlewareStack.Invoke(new DefaultHttpContext());
- }
-
- _mres.Wait();
- }
-}
diff --git a/src/Middleware/ConcurrencyLimiter/sample/ConcurrencyLimiterSample.csproj b/src/Middleware/ConcurrencyLimiter/sample/ConcurrencyLimiterSample.csproj
deleted file mode 100644
index a7f5b4921686..000000000000
--- a/src/Middleware/ConcurrencyLimiter/sample/ConcurrencyLimiterSample.csproj
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
- $(DefaultNetCoreTargetFramework)
-
-
-
-
-
-
-
-
-
diff --git a/src/Middleware/ConcurrencyLimiter/sample/Properties/launchSettings.json b/src/Middleware/ConcurrencyLimiter/sample/Properties/launchSettings.json
deleted file mode 100644
index 4e765db3c30f..000000000000
--- a/src/Middleware/ConcurrencyLimiter/sample/Properties/launchSettings.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "iisSettings": {
- "windowsAuthentication": false,
- "anonymousAuthentication": true,
- "iisExpress": {
- "applicationUrl": "http://localhost:54272/",
- "sslPort": 44373
- }
- },
- "profiles": {
- "ConcurrencyLimiterSample": {
- "commandName": "Project",
- "launchBrowser": true,
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- },
- "applicationUrl": "https://localhost:5001;http://localhost:5000"
- },
- "IIS Express": {
- "commandName": "IISExpress",
- "launchBrowser": true,
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- }
- }
-}
diff --git a/src/Middleware/ConcurrencyLimiter/sample/Startup.cs b/src/Middleware/ConcurrencyLimiter/sample/Startup.cs
deleted file mode 100644
index 636311b2013a..000000000000
--- a/src/Middleware/ConcurrencyLimiter/sample/Startup.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace ConcurrencyLimiterSample;
-
-public class Startup
-{
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddStackPolicy(options =>
- {
- options.MaxConcurrentRequests = 2;
- options.RequestQueueLimit = 25;
- });
- }
-
- public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
- {
-#pragma warning disable CS0618 // Type or member is obsolete
- app.UseConcurrencyLimiter();
-#pragma warning restore CS0618 // Type or member is obsolete
- app.Run(async context =>
- {
- Task.Delay(100).Wait(); // 100ms sync-over-async
-
- await context.Response.WriteAsync("Hello World!");
- });
- }
-
- public static Task Main(string[] args)
- {
- return new HostBuilder()
- .ConfigureWebHost(webHostBuilder =>
- {
- webHostBuilder
- .UseKestrel()
- .UseStartup();
- })
- .Build()
- .RunAsync();
- }
-}
diff --git a/src/Middleware/ConcurrencyLimiter/src/ConcurrencyLimiterEventSource.cs b/src/Middleware/ConcurrencyLimiter/src/ConcurrencyLimiterEventSource.cs
deleted file mode 100644
index 0cc1c3c7c4a3..000000000000
--- a/src/Middleware/ConcurrencyLimiter/src/ConcurrencyLimiterEventSource.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Diagnostics.Tracing;
-using Microsoft.Extensions.Internal;
-
-namespace Microsoft.AspNetCore.ConcurrencyLimiter;
-
-internal sealed class ConcurrencyLimiterEventSource : EventSource
-{
- public static readonly ConcurrencyLimiterEventSource Log = new ConcurrencyLimiterEventSource();
- private static readonly QueueFrame CachedNonTimerResult = new QueueFrame(timer: null, parent: Log);
-
-#pragma warning disable IDE0052 // Remove unread private members (2021-02-02: These ARE set in OnEventCommand - the the IDE0052 analyzer is incorrect at this time)
- private PollingCounter? _rejectedRequestsCounter;
- private PollingCounter? _queueLengthCounter;
-#pragma warning restore IDE0052 // Remove unread private members
-
- private EventCounter? _queueDuration;
-
- private long _rejectedRequests;
- private int _queueLength;
-
- internal ConcurrencyLimiterEventSource()
- : base("Microsoft.AspNetCore.ConcurrencyLimiter")
- {
- }
-
- // Used for testing
- internal ConcurrencyLimiterEventSource(string eventSourceName)
- : base(eventSourceName, EventSourceSettings.EtwManifestEventFormat)
- {
- }
-
- [Event(1, Level = EventLevel.Warning)]
- public void RequestRejected()
- {
- Interlocked.Increment(ref _rejectedRequests);
- WriteEvent(1);
- }
-
- [NonEvent]
- public void QueueSkipped()
- {
- if (IsEnabled())
- {
- _queueDuration!.WriteMetric(0);
- }
- }
-
- [NonEvent]
- public QueueFrame QueueTimer()
- {
- Interlocked.Increment(ref _queueLength);
-
- if (IsEnabled())
- {
- return new QueueFrame(ValueStopwatch.StartNew(), this);
- }
-
- return CachedNonTimerResult;
- }
-
- internal struct QueueFrame : IDisposable
- {
- private readonly ValueStopwatch? _timer;
- private readonly ConcurrencyLimiterEventSource _parent;
-
- public QueueFrame(ValueStopwatch? timer, ConcurrencyLimiterEventSource parent)
- {
- _timer = timer;
- _parent = parent;
- }
-
- public void Dispose()
- {
- Interlocked.Decrement(ref _parent._queueLength);
-
- if (_parent.IsEnabled() && _timer != null)
- {
- var duration = _timer.Value.GetElapsedTime().TotalMilliseconds;
- _parent._queueDuration!.WriteMetric(duration);
- }
- }
- }
-
- protected override void OnEventCommand(EventCommandEventArgs command)
- {
- if (command.Command == EventCommand.Enable)
- {
- _rejectedRequestsCounter ??= new PollingCounter("requests-rejected", this, () => Volatile.Read(ref _rejectedRequests))
- {
- DisplayName = "Rejected Requests",
- };
-
- _queueLengthCounter ??= new PollingCounter("queue-length", this, () => Volatile.Read(ref _queueLength))
- {
- DisplayName = "Queue Length",
- };
-
- _queueDuration ??= new EventCounter("queue-duration", this)
- {
- DisplayName = "Average Time in Queue",
- };
- }
- }
-}
diff --git a/src/Middleware/ConcurrencyLimiter/src/ConcurrencyLimiterExtensions.cs b/src/Middleware/ConcurrencyLimiter/src/ConcurrencyLimiterExtensions.cs
deleted file mode 100644
index 2f2ecda96e9c..000000000000
--- a/src/Middleware/ConcurrencyLimiter/src/ConcurrencyLimiterExtensions.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using Microsoft.AspNetCore.ConcurrencyLimiter;
-
-namespace Microsoft.AspNetCore.Builder;
-
-///
-/// Extension methods for adding the to an application.
-///
-public static class ConcurrencyLimiterExtensions
-{
- ///
- /// Adds the to limit the number of concurrently-executing requests.
- ///
- /// The .
- /// The .
- [Obsolete("Concurrency Limiter middleware has been deprecated and will be removed in a future release. Update the app to use concurrency features in rate limiting middleware. For more information, see https://aka.ms/aspnet/rate-limiting")]
- public static IApplicationBuilder UseConcurrencyLimiter(this IApplicationBuilder app)
- {
- ArgumentNullException.ThrowIfNull(app);
-
- return app.UseMiddleware();
- }
-}
diff --git a/src/Middleware/ConcurrencyLimiter/src/ConcurrencyLimiterMiddleware.cs b/src/Middleware/ConcurrencyLimiter/src/ConcurrencyLimiterMiddleware.cs
deleted file mode 100644
index 8caf22811472..000000000000
--- a/src/Middleware/ConcurrencyLimiter/src/ConcurrencyLimiterMiddleware.cs
+++ /dev/null
@@ -1,100 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-
-namespace Microsoft.AspNetCore.ConcurrencyLimiter;
-
-///
-/// Limits the number of concurrent requests allowed in the application.
-///
-[Obsolete("Concurrency Limiter middleware has been deprecated and will be removed in a future release. Update the app to use concurrency features in rate limiting middleware. For more information, see https://aka.ms/aspnet/rate-limiting")]
-public partial class ConcurrencyLimiterMiddleware
-{
- private readonly IQueuePolicy _queuePolicy;
- private readonly RequestDelegate _next;
- private readonly RequestDelegate _onRejected;
- private readonly ILogger _logger;
-
- ///
- /// Creates a new .
- ///
- /// The representing the next middleware in the pipeline.
- /// The used for logging.
- /// The queueing strategy to use for the server.
- /// The options for the middleware, currently containing the 'OnRejected' callback.
- public ConcurrencyLimiterMiddleware(RequestDelegate next, ILoggerFactory loggerFactory, IQueuePolicy queue, IOptions options)
- {
- if (options.Value.OnRejected == null)
- {
- throw new ArgumentException("The value of 'options.OnRejected' must not be null.", nameof(options));
- }
-
- _next = next;
- _logger = loggerFactory.CreateLogger();
- _onRejected = options.Value.OnRejected;
- _queuePolicy = queue;
- }
-
- ///
- /// Invokes the logic of the middleware.
- ///
- /// The .
- /// A that completes when the request leaves.
- public async Task Invoke(HttpContext context)
- {
- var waitInQueueTask = _queuePolicy.TryEnterAsync();
-
- // Make sure we only ever call GetResult once on the TryEnterAsync ValueTask b/c it resets.
- bool result;
-
- if (waitInQueueTask.IsCompleted)
- {
- ConcurrencyLimiterEventSource.Log.QueueSkipped();
- result = waitInQueueTask.Result;
- }
- else
- {
- using (ConcurrencyLimiterEventSource.Log.QueueTimer())
- {
- result = await waitInQueueTask;
- }
- }
-
- if (result)
- {
- try
- {
- await _next(context);
- }
- finally
- {
- _queuePolicy.OnExit();
- }
- }
- else
- {
- ConcurrencyLimiterEventSource.Log.RequestRejected();
- ConcurrencyLimiterLog.RequestRejectedQueueFull(_logger);
- context.Response.StatusCode = StatusCodes.Status503ServiceUnavailable;
- await _onRejected(context);
- }
- }
-
- private static partial class ConcurrencyLimiterLog
- {
- [LoggerMessage(1, LogLevel.Debug, "MaxConcurrentRequests limit reached, request has been queued. Current active requests: {ActiveRequests}.", EventName = "RequestEnqueued")]
- internal static partial void RequestEnqueued(ILogger logger, int activeRequests);
-
- [LoggerMessage(2, LogLevel.Debug, "Request dequeued. Current active requests: {ActiveRequests}.", EventName = "RequestDequeued")]
- internal static partial void RequestDequeued(ILogger logger, int activeRequests);
-
- [LoggerMessage(3, LogLevel.Debug, "Below MaxConcurrentRequests limit, running request immediately. Current active requests: {ActiveRequests}", EventName = "RequestRunImmediately")]
- internal static partial void RequestRunImmediately(ILogger logger, int activeRequests);
-
- [LoggerMessage(4, LogLevel.Debug, "Currently at the 'RequestQueueLimit', rejecting this request with a '503 server not available' error", EventName = "RequestRejectedQueueFull")]
- internal static partial void RequestRejectedQueueFull(ILogger logger);
- }
-}
diff --git a/src/Middleware/ConcurrencyLimiter/src/ConcurrencyLimiterOptions.cs b/src/Middleware/ConcurrencyLimiter/src/ConcurrencyLimiterOptions.cs
deleted file mode 100644
index ec71e689211b..000000000000
--- a/src/Middleware/ConcurrencyLimiter/src/ConcurrencyLimiterOptions.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using Microsoft.AspNetCore.Http;
-
-namespace Microsoft.AspNetCore.ConcurrencyLimiter;
-
-///
-/// Specifies options for the .
-///
-[Obsolete("Concurrency Limiter middleware has been deprecated and will be removed in a future release. Update the app to use concurrency features in rate limiting middleware. For more information, see https://aka.ms/aspnet/rate-limiting")]
-public class ConcurrencyLimiterOptions
-{
- ///
- /// A that handles requests rejected by this middleware.
- /// If it doesn't modify the response, an empty 503 response will be written.
- ///
- public RequestDelegate OnRejected { get; set; } = context =>
- {
- return Task.CompletedTask;
- };
-}
diff --git a/src/Middleware/ConcurrencyLimiter/src/Microsoft.AspNetCore.ConcurrencyLimiter.csproj b/src/Middleware/ConcurrencyLimiter/src/Microsoft.AspNetCore.ConcurrencyLimiter.csproj
deleted file mode 100644
index b2936f52a565..000000000000
--- a/src/Middleware/ConcurrencyLimiter/src/Microsoft.AspNetCore.ConcurrencyLimiter.csproj
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
- ASP.NET Core middleware for queuing incoming HTTP requests, to avoid threadpool starvation.
- $(DefaultNetCoreTargetFramework)
- true
- aspnetcore;queue;queuing
- enable
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Middleware/ConcurrencyLimiter/src/PublicAPI.Shipped.txt b/src/Middleware/ConcurrencyLimiter/src/PublicAPI.Shipped.txt
deleted file mode 100644
index cc188c5a2d4d..000000000000
--- a/src/Middleware/ConcurrencyLimiter/src/PublicAPI.Shipped.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-#nullable enable
-Microsoft.AspNetCore.Builder.ConcurrencyLimiterExtensions
-Microsoft.AspNetCore.ConcurrencyLimiter.ConcurrencyLimiterMiddleware
-Microsoft.AspNetCore.ConcurrencyLimiter.ConcurrencyLimiterMiddleware.ConcurrencyLimiterMiddleware(Microsoft.AspNetCore.Http.RequestDelegate! next, Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory, Microsoft.AspNetCore.ConcurrencyLimiter.IQueuePolicy! queue, Microsoft.Extensions.Options.IOptions! options) -> void
-Microsoft.AspNetCore.ConcurrencyLimiter.ConcurrencyLimiterMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext! context) -> System.Threading.Tasks.Task!
-Microsoft.AspNetCore.ConcurrencyLimiter.ConcurrencyLimiterOptions
-Microsoft.AspNetCore.ConcurrencyLimiter.ConcurrencyLimiterOptions.ConcurrencyLimiterOptions() -> void
-Microsoft.AspNetCore.ConcurrencyLimiter.ConcurrencyLimiterOptions.OnRejected.get -> Microsoft.AspNetCore.Http.RequestDelegate!
-Microsoft.AspNetCore.ConcurrencyLimiter.ConcurrencyLimiterOptions.OnRejected.set -> void
-Microsoft.AspNetCore.ConcurrencyLimiter.IQueuePolicy
-Microsoft.AspNetCore.ConcurrencyLimiter.IQueuePolicy.OnExit() -> void
-Microsoft.AspNetCore.ConcurrencyLimiter.IQueuePolicy.TryEnterAsync() -> System.Threading.Tasks.ValueTask
-Microsoft.AspNetCore.ConcurrencyLimiter.QueuePolicyOptions
-Microsoft.AspNetCore.ConcurrencyLimiter.QueuePolicyOptions.MaxConcurrentRequests.get -> int
-Microsoft.AspNetCore.ConcurrencyLimiter.QueuePolicyOptions.MaxConcurrentRequests.set -> void
-Microsoft.AspNetCore.ConcurrencyLimiter.QueuePolicyOptions.QueuePolicyOptions() -> void
-Microsoft.AspNetCore.ConcurrencyLimiter.QueuePolicyOptions.RequestQueueLimit.get -> int
-Microsoft.AspNetCore.ConcurrencyLimiter.QueuePolicyOptions.RequestQueueLimit.set -> void
-Microsoft.Extensions.DependencyInjection.QueuePolicyServiceCollectionExtensions
-static Microsoft.AspNetCore.Builder.ConcurrencyLimiterExtensions.UseConcurrencyLimiter(this Microsoft.AspNetCore.Builder.IApplicationBuilder! app) -> Microsoft.AspNetCore.Builder.IApplicationBuilder!
-static Microsoft.Extensions.DependencyInjection.QueuePolicyServiceCollectionExtensions.AddQueuePolicy(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
-static Microsoft.Extensions.DependencyInjection.QueuePolicyServiceCollectionExtensions.AddStackPolicy(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
diff --git a/src/Middleware/ConcurrencyLimiter/src/PublicAPI.Unshipped.txt b/src/Middleware/ConcurrencyLimiter/src/PublicAPI.Unshipped.txt
deleted file mode 100644
index 7dc5c58110bf..000000000000
--- a/src/Middleware/ConcurrencyLimiter/src/PublicAPI.Unshipped.txt
+++ /dev/null
@@ -1 +0,0 @@
-#nullable enable
diff --git a/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/BasePolicy.cs b/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/BasePolicy.cs
deleted file mode 100644
index ed3ec46ddd5b..000000000000
--- a/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/BasePolicy.cs
+++ /dev/null
@@ -1,98 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Collections.Concurrent;
-using System.Threading.RateLimiting;
-using Microsoft.Extensions.Options;
-using Limiter = System.Threading.RateLimiting.ConcurrencyLimiter;
-using LimiterOptions = System.Threading.RateLimiting.ConcurrencyLimiterOptions;
-
-namespace Microsoft.AspNetCore.ConcurrencyLimiter;
-
-internal class BasePolicy : IQueuePolicy, IDisposable
-{
- private readonly Limiter _limiter;
- private readonly ConcurrentQueue _leases = new ConcurrentQueue();
-
- public int TotalRequests => _leases.Count;
-
- public BasePolicy(IOptions options, QueueProcessingOrder order)
- {
- var queuePolicyOptions = options.Value;
-
- var maxConcurrentRequests = queuePolicyOptions.MaxConcurrentRequests;
- if (maxConcurrentRequests <= 0)
- {
- throw new ArgumentException("MaxConcurrentRequests must be a positive integer.", nameof(options));
- }
-
- var requestQueueLimit = queuePolicyOptions.RequestQueueLimit;
- if (requestQueueLimit < 0)
- {
- throw new ArgumentException("The RequestQueueLimit cannot be a negative number.", nameof(options));
- }
-
- _limiter = new Limiter(new LimiterOptions
- {
- PermitLimit = maxConcurrentRequests,
- QueueProcessingOrder = order,
- QueueLimit = requestQueueLimit
- });
- }
-
- public ValueTask TryEnterAsync()
- {
- // a return value of 'false' indicates that the request is rejected
- // a return value of 'true' indicates that the request may proceed
-
- var lease = _limiter.AttemptAcquire();
- if (lease.IsAcquired)
- {
- _leases.Enqueue(lease);
- return ValueTask.FromResult(true);
- }
-
- var task = _limiter.AcquireAsync();
- if (task.IsCompletedSuccessfully)
- {
- lease = task.Result;
- if (lease.IsAcquired)
- {
- _leases.Enqueue(lease);
- return ValueTask.FromResult(true);
- }
-
- return ValueTask.FromResult(false);
- }
-
- return Awaited(task);
- }
-
- public void OnExit()
- {
- if (!_leases.TryDequeue(out var lease))
- {
- throw new InvalidOperationException("No outstanding leases.");
- }
-
- lease.Dispose();
- }
-
- public void Dispose()
- {
- _limiter.Dispose();
- }
-
- private async ValueTask Awaited(ValueTask task)
- {
- var lease = await task;
-
- if (lease.IsAcquired)
- {
- _leases.Enqueue(lease);
- return true;
- }
-
- return false;
- }
-}
diff --git a/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/IQueuePolicy.cs b/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/IQueuePolicy.cs
deleted file mode 100644
index 4ec61663fed2..000000000000
--- a/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/IQueuePolicy.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace Microsoft.AspNetCore.ConcurrencyLimiter;
-
-///
-/// Queueing policies, meant to be used with the .
-///
-public interface IQueuePolicy
-{
- ///
- /// Called for every incoming request.
- /// When it returns 'true' the request procedes to the server.
- /// When it returns 'false' the request is rejected immediately.
- ///
- ValueTask TryEnterAsync();
-
- ///
- /// Called after successful requests have been returned from the server.
- /// Does NOT get called for rejected requests.
- ///
- void OnExit();
-}
diff --git a/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/QueuePolicy.cs b/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/QueuePolicy.cs
deleted file mode 100644
index cea11a8a4f6c..000000000000
--- a/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/QueuePolicy.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Threading.RateLimiting;
-using Microsoft.Extensions.Options;
-
-namespace Microsoft.AspNetCore.ConcurrencyLimiter;
-
-internal sealed class QueuePolicy : BasePolicy
-{
- public QueuePolicy(IOptions options)
- : base(options, QueueProcessingOrder.OldestFirst)
- {
- }
-}
diff --git a/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/QueuePolicyOptions.cs b/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/QueuePolicyOptions.cs
deleted file mode 100644
index 42f9add3e34a..000000000000
--- a/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/QueuePolicyOptions.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace Microsoft.AspNetCore.ConcurrencyLimiter;
-
-///
-/// Specifies options for the
-///
-public class QueuePolicyOptions
-{
- ///
- /// Maximum number of concurrent requests. Any extras will be queued on the server.
- /// This option is highly application dependant, and must be configured by the application.
- ///
- public int MaxConcurrentRequests { get; set; }
-
- ///
- /// Maximum number of queued requests before the server starts rejecting connections with '503 Service Unavailable'.
- /// This option is highly application dependant, and must be configured by the application.
- ///
- public int RequestQueueLimit { get; set; }
-}
diff --git a/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/QueuePolicyServiceCollectionExtensions.cs b/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/QueuePolicyServiceCollectionExtensions.cs
deleted file mode 100644
index 88f063f72259..000000000000
--- a/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/QueuePolicyServiceCollectionExtensions.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using Microsoft.AspNetCore.ConcurrencyLimiter;
-
-namespace Microsoft.Extensions.DependencyInjection;
-
-///
-/// Contains methods for specifying which queue the middleware should use.
-///
-public static class QueuePolicyServiceCollectionExtensions
-{
- ///
- /// Tells to use a FIFO queue as its queueing strategy.
- ///
- /// The to add services to.
- /// Set the options used by the queue.
- /// Mandatory, since must be provided.
- ///
- public static IServiceCollection AddQueuePolicy(this IServiceCollection services, Action configure)
- {
- services.Configure(configure);
- services.AddSingleton();
- return services;
- }
-
- ///
- /// Tells to use a LIFO stack as its queueing strategy.
- ///
- /// The to add services to.
- /// Set the options used by the queue.
- /// Mandatory, since must be provided.
- ///
- public static IServiceCollection AddStackPolicy(this IServiceCollection services, Action configure)
- {
- services.Configure(configure);
- services.AddSingleton();
- return services;
- }
-}
diff --git a/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/StackPolicy.cs b/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/StackPolicy.cs
deleted file mode 100644
index 0dbd580ac374..000000000000
--- a/src/Middleware/ConcurrencyLimiter/src/QueuePolicies/StackPolicy.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Threading.RateLimiting;
-using Microsoft.Extensions.Options;
-
-namespace Microsoft.AspNetCore.ConcurrencyLimiter;
-
-internal sealed class StackPolicy : BasePolicy
-{
- public StackPolicy(IOptions options)
- : base(options, QueueProcessingOrder.NewestFirst)
- {
- }
-}
diff --git a/src/Middleware/ConcurrencyLimiter/test/ConcurrencyLimiterEventSourceTests.cs b/src/Middleware/ConcurrencyLimiter/test/ConcurrencyLimiterEventSourceTests.cs
deleted file mode 100644
index 61b5b99b9d87..000000000000
--- a/src/Middleware/ConcurrencyLimiter/test/ConcurrencyLimiterEventSourceTests.cs
+++ /dev/null
@@ -1,137 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Globalization;
-using System.Diagnostics.Tracing;
-using Microsoft.AspNetCore.Internal;
-using Microsoft.AspNetCore.InternalTesting;
-using Microsoft.Extensions.Logging;
-
-namespace Microsoft.AspNetCore.ConcurrencyLimiter.Tests;
-
-public class ConcurrencyLimiterEventSourceTests : LoggedTest
-{
- [Fact]
- public void MatchesNameAndGuid()
- {
- var eventSource = new ConcurrencyLimiterEventSource();
-
- Assert.Equal("Microsoft.AspNetCore.ConcurrencyLimiter", eventSource.Name);
- Assert.Equal(Guid.Parse("a605548a-6963-55cf-f000-99a6013deb01", CultureInfo.InvariantCulture), eventSource.Guid);
- }
-
- [Fact]
- public void RecordsRequestsRejected()
- {
- // Arrange
- var expectedId = 1;
- var eventListener = new TestEventListener(expectedId);
- var eventSource = GetConcurrencyLimiterEventSource();
- eventListener.EnableEvents(eventSource, EventLevel.Informational);
-
- // Act
- eventSource.RequestRejected();
-
- // Assert
- var eventData = eventListener.EventData;
- Assert.NotNull(eventData);
- Assert.Equal(expectedId, eventData.EventId);
- Assert.Equal(EventLevel.Warning, eventData.Level);
- Assert.Same(eventSource, eventData.EventSource);
- Assert.Null(eventData.Message);
- Assert.Empty(eventData.Payload);
- }
-
- [Fact]
- public async Task TracksQueueLength()
- {
- // Arrange
- using var eventSource = GetConcurrencyLimiterEventSource();
-
- using var eventListener = new TestCounterListener(LoggerFactory, eventSource.Name, [
- "queue-length",
- "queue-duration",
- "requests-rejected",
- ]);
-
- using var timeoutTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30));
-
- var lengthValues = eventListener.GetCounterValues("queue-length", timeoutTokenSource.Token);
-
- eventListener.EnableEvents(eventSource, EventLevel.Informational, EventKeywords.None,
- new Dictionary
- {
- {"EventCounterIntervalSec", ".1" }
- });
-
- // Act
- eventSource.RequestRejected();
-
- await WaitForCounterValue(lengthValues, expectedValue: 0, Logger);
- using (eventSource.QueueTimer())
- {
- await WaitForCounterValue(lengthValues, expectedValue: 1, Logger);
-
- using (eventSource.QueueTimer())
- {
- await WaitForCounterValue(lengthValues, expectedValue: 2, Logger);
- }
-
- await WaitForCounterValue(lengthValues, expectedValue: 1, Logger);
- }
-
- await WaitForCounterValue(lengthValues, expectedValue: 0, Logger);
- }
-
- [Fact]
- public async Task TracksDurationSpentInQueue()
- {
- // Arrange
- using var eventSource = GetConcurrencyLimiterEventSource();
-
- using var eventListener = new TestCounterListener(LoggerFactory, eventSource.Name, [
- "queue-length",
- "queue-duration",
- "requests-rejected",
- ]);
-
- using var timeoutTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(5));
-
- var durationValues = eventListener.GetCounterValues("queue-duration", timeoutTokenSource.Token);
-
- eventListener.EnableEvents(eventSource, EventLevel.Informational, EventKeywords.None,
- new Dictionary
- {
- {"EventCounterIntervalSec", ".1" }
- });
-
- // Act
- await WaitForCounterValue(durationValues, expectedValue: 0, Logger);
-
- using (eventSource.QueueTimer())
- {
- await WaitForCounterValue(durationValues, expectedValue: 0, Logger);
- }
-
- // check that something (anything!) has been written
- while (await durationValues.Values.MoveNextAsync())
- {
- if (durationValues.Values.Current > 0)
- {
- return;
- }
- }
-
- throw new TimeoutException();
- }
-
- private static async Task WaitForCounterValue(CounterValues values, double expectedValue, ILogger logger)
- {
- await values.Values.WaitForValueAsync(expectedValue, values.CounterName, logger);
- }
-
- private static ConcurrencyLimiterEventSource GetConcurrencyLimiterEventSource()
- {
- return new ConcurrencyLimiterEventSource(Guid.NewGuid().ToString());
- }
-}
diff --git a/src/Middleware/ConcurrencyLimiter/test/Microsoft.AspNetCore.ConcurrencyLimiter.Tests.csproj b/src/Middleware/ConcurrencyLimiter/test/Microsoft.AspNetCore.ConcurrencyLimiter.Tests.csproj
deleted file mode 100644
index ad2734d58177..000000000000
--- a/src/Middleware/ConcurrencyLimiter/test/Microsoft.AspNetCore.ConcurrencyLimiter.Tests.csproj
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
- $(DefaultNetCoreTargetFramework)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Middleware/ConcurrencyLimiter/test/MiddlewareTests.cs b/src/Middleware/ConcurrencyLimiter/test/MiddlewareTests.cs
deleted file mode 100644
index b84689771284..000000000000
--- a/src/Middleware/ConcurrencyLimiter/test/MiddlewareTests.cs
+++ /dev/null
@@ -1,237 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Threading.Tasks.Sources;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.InternalTesting;
-
-namespace Microsoft.AspNetCore.ConcurrencyLimiter.Tests;
-
-public class MiddlewareTests
-{
- [Fact]
- public async Task RequestsCallNextIfQueueReturnsTrue()
- {
- var flag = false;
-
- var middleware = TestUtils.CreateTestMiddleware(
- queue: TestQueue.AlwaysTrue,
- next: httpContext =>
- {
- flag = true;
- return Task.CompletedTask;
- });
-
- await middleware.Invoke(new DefaultHttpContext());
- Assert.True(flag);
- }
-
- [Fact]
- public async Task RequestRejectsIfQueueReturnsFalse()
- {
- bool onRejectedInvoked = false;
-
- var middleware = TestUtils.CreateTestMiddleware(
- queue: TestQueue.AlwaysFalse,
- onRejected: httpContext =>
- {
- onRejectedInvoked = true;
- return Task.CompletedTask;
- });
-
- var context = new DefaultHttpContext();
- await middleware.Invoke(context).DefaultTimeout();
- Assert.True(onRejectedInvoked);
- Assert.Equal(StatusCodes.Status503ServiceUnavailable, context.Response.StatusCode);
- }
-
- [Fact]
- public async Task RequestsDoesNotEnterIfQueueFull()
- {
- var middleware = TestUtils.CreateTestMiddleware(
- queue: TestQueue.AlwaysFalse,
- next: httpContext =>
- {
- // throttle should bounce the request; it should never get here
- throw new DivideByZeroException();
- });
-
- await middleware.Invoke(new DefaultHttpContext()).DefaultTimeout();
- }
-
- [Fact]
- public void IncomingRequestsFillUpQueue()
- {
- var testQueue = TestQueue.AlwaysBlock;
- var middleware = TestUtils.CreateTestMiddleware(testQueue);
-
- Assert.Equal(0, testQueue.QueuedRequests);
-
- var task1 = middleware.Invoke(new DefaultHttpContext());
- Assert.Equal(1, testQueue.QueuedRequests);
- Assert.False(task1.IsCompleted);
-
- var task2 = middleware.Invoke(new DefaultHttpContext());
- Assert.Equal(2, testQueue.QueuedRequests);
- Assert.False(task2.IsCompleted);
- }
-
- [Fact]
- public void EventCountersTrackQueuedRequests()
- {
- var blocker = new TaskCompletionSource();
-
- var testQueue = new TestQueue(
- onTryEnter: async (_) =>
- {
- return await blocker.Task;
- });
- var middleware = TestUtils.CreateTestMiddleware(testQueue);
-
- Assert.Equal(0, testQueue.QueuedRequests);
-
- var task1 = middleware.Invoke(new DefaultHttpContext());
- Assert.False(task1.IsCompleted);
- Assert.Equal(1, testQueue.QueuedRequests);
-
- blocker.SetResult(true);
-
- Assert.Equal(0, testQueue.QueuedRequests);
- }
-
- [Fact]
- public async Task QueueOnExitCalledEvenIfNextErrors()
- {
- var flag = false;
-
- var testQueue = new TestQueue(
- onTryEnter: (_) => true,
- onExit: () => { flag = true; });
-
- var middleware = TestUtils.CreateTestMiddleware(
- queue: testQueue,
- next: httpContext =>
- {
- throw new DivideByZeroException();
- });
-
- Assert.Equal(0, testQueue.QueuedRequests);
- await Assert.ThrowsAsync(() => middleware.Invoke(new DefaultHttpContext())).DefaultTimeout();
-
- Assert.Equal(0, testQueue.QueuedRequests);
- Assert.True(flag);
- }
-
- [Fact]
- public async Task ExceptionThrownDuringOnRejected()
- {
- TaskCompletionSource tcs = new TaskCompletionSource();
-
- var concurrent = 0;
- var testQueue = new TestQueue(
- onTryEnter: (testQueue) =>
- {
- if (concurrent > 0)
- {
- return false;
- }
- else
- {
- concurrent++;
- return true;
- }
- },
- onExit: () => { concurrent--; });
-
- var middleware = TestUtils.CreateTestMiddleware(
- queue: testQueue,
- onRejected: httpContext =>
- {
- throw new DivideByZeroException();
- },
- next: httpContext =>
- {
- return tcs.Task;
- });
-
- // the first request enters the server, and is blocked by the tcs
- var firstRequest = middleware.Invoke(new DefaultHttpContext());
- Assert.Equal(1, concurrent);
- Assert.Equal(0, testQueue.QueuedRequests);
-
- // the second request is rejected with a 503 error. During the rejection, an error occurs
- var context = new DefaultHttpContext();
- await Assert.ThrowsAsync(() => middleware.Invoke(context)).DefaultTimeout();
- Assert.Equal(StatusCodes.Status503ServiceUnavailable, context.Response.StatusCode);
- Assert.Equal(1, concurrent);
- Assert.Equal(0, testQueue.QueuedRequests);
-
- // the first request is unblocked, and the queue continues functioning as expected
- tcs.SetResult();
- Assert.True(firstRequest.IsCompletedSuccessfully);
- Assert.Equal(0, concurrent);
- Assert.Equal(0, testQueue.QueuedRequests);
-
- var thirdRequest = middleware.Invoke(new DefaultHttpContext());
- Assert.True(thirdRequest.IsCompletedSuccessfully);
- Assert.Equal(0, concurrent);
- Assert.Equal(0, testQueue.QueuedRequests);
- }
-
- [Fact]
- public async Task MiddlewareOnlyCallsGetResultOnce()
- {
- var flag = false;
-
- var queue = new TestQueueForValueTask();
- var middleware = TestUtils.CreateTestMiddleware(
- queue,
- next: async context =>
- {
- await Task.CompletedTask;
- flag = true;
- });
-
- await middleware.Invoke(new DefaultHttpContext());
-
- Assert.True(flag);
- }
-
- private class TestQueueForValueTask : IQueuePolicy
- {
- public TestValueResult Source;
- public TestQueueForValueTask()
- {
- Source = new TestValueResult();
- }
-
- public ValueTask TryEnterAsync()
- {
- return new ValueTask(Source, 0);
- }
-
- public void OnExit() { }
- }
-
- private class TestValueResult : IValueTaskSource
- {
- private bool _getResultCalled;
-
- public bool GetResult(short token)
- {
- Assert.False(_getResultCalled);
- _getResultCalled = true;
- return true;
- }
-
- public ValueTaskSourceStatus GetStatus(short token)
- {
- return ValueTaskSourceStatus.Succeeded;
- }
-
- public void OnCompleted(Action