namespace NetAdmin.Host.Middlewares;
///
/// 安全停机中间件
///
///
/// 放在所有中间件最前面
///
public sealed class SafetyShopHostMiddleware(RequestDelegate next)
{
private static long _connections;
private static bool _trafficOff;
///
/// 当前连接数
///
public static long Connections => Interlocked.Read(ref _connections);
///
/// 是否已停机
///
public static bool IsShutdown => Volatile.Read(ref _trafficOff);
///
/// 停机处理
///
public static void OnStopping()
{
Stop();
while (Interlocked.Read(ref _connections) > 0) {
Thread.Sleep(10);
}
}
///
/// 系统启机
///
public static void Start()
{
Volatile.Write(ref _trafficOff, false);
}
///
/// 系统停机
///
public static void Stop()
{
Volatile.Write(ref _trafficOff, true);
}
///
/// 主函数
///
public async Task InvokeAsync(HttpContext context)
{
if (Volatile.Read(ref _trafficOff) &&
!context.Request.Path.StartsWithSegments($"/{Chars.FLG_PATH_API_RPOBE}")) {
context.Response.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
return;
}
// webSocket链接不参与计算
if (context.Request.Path.StartsWithSegments($"/{Chars.FLG_PATH_WEBSOCKET_PREFIX}")) {
await next(context).ConfigureAwait(false);
}
else {
_ = Interlocked.Increment(ref _connections);
await next(context).ConfigureAwait(false);
_ = Interlocked.Decrement(ref _connections);
}
}
}