Files
SPT-Server-Build/SPTarkov.Server/Services/NoGCRegionMiddleware.cs
T
2025-10-20 12:01:26 +00:00

78 lines
2.3 KiB
C#

using System.Runtime;
using SPTarkov.Server.Core.Models.Spt.Config;
using SPTarkov.Server.Core.Servers;
namespace SPTarkov.Server.Services;
// ReSharper disable once InconsistentNaming
public class NoGCRegionMiddleware(RequestDelegate next)
{
private static long _activeRequests;
private static bool OtherRequestsActive
{
get { return Interlocked.Read(ref _activeRequests) > 1; }
}
public async Task InvokeAsync(HttpContext context)
{
Interlocked.Increment(ref _activeRequests);
var config = context.RequestServices.GetRequiredService<ConfigServer>().GetConfig<CoreConfig>();
// if no other requests are running, start the no GC region, otherwise dont start it
if (!OtherRequestsActive)
{
if (config.EnableNoGCRegions && GCSettings.LatencyMode != GCLatencyMode.NoGCRegion)
{
try
{
GC.TryStartNoGCRegion(
1024L * 1024L * 1024L * config.NoGCRegionMaxMemoryGB,
1024L * 1024L * 1024L * config.NoGCRegionMaxLOHMemoryGB,
true
);
}
catch (Exception)
{
// ignored, we keep going
}
}
}
try
{
await next(context);
}
finally
{
Interlocked.Decrement(ref _activeRequests);
}
// if no other requests are running, end the no GC region, otherwise dont stop it as other requests need it still
if (!OtherRequestsActive)
{
if (config.EnableNoGCRegions && GCSettings.LatencyMode == GCLatencyMode.NoGCRegion)
{
try
{
GC.EndNoGCRegion();
}
catch (Exception)
{
// ignored, we dont care about handling this
}
}
}
}
}
// ReSharper disable once InconsistentNaming
public static class NoGCRegionMiddlewareExtensions
{
// ReSharper disable once InconsistentNaming
public static IApplicationBuilder UseNoGCRegions(this IApplicationBuilder builder)
{
return builder.UseMiddleware<NoGCRegionMiddleware>();
}
}