using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; namespace Admin.NET.Plugin.AiDOP.DataPlatform.Executors; /// /// 出站总闸门。三个推送入口(事件驱动 Worker、60 秒 Job、手工重投) /// 以及领料单号同步都汇到这里;关闭时不发送、不改 mdp_outbox 状态、不烧重试。 /// public sealed class MdpOutboundGate : ISingleton { public const string DisabledMessage = "出站推送已关闭,mdp_outbox 只入队不发送"; private readonly IOptionsMonitor _options; private readonly ILogger _logger; private int _announced; private long _refused; public MdpOutboundGate(IOptionsMonitor options, ILoggerFactory loggerFactory) { _options = options; _logger = loggerFactory.CreateLogger(nameof(MdpOutboundGate)); } public bool IsEnabled => _options.CurrentValue.Enabled; public long RefusedCount => Interlocked.Read(ref _refused); /// 进程内只打一次。由启动即跑的出站 Job 调用,保证关着的时候日志里能看见。 public void AnnounceIfDisabled() { if (IsEnabled || Interlocked.Exchange(ref _announced, 1) == 1) return; _logger.LogWarning("[MdpOutboundGate] {Message}", DisabledMessage); } /// 关闭时返回 的结果;调用方不得据此改 outbox 行。 public MdpPushResult? TryHold() { if (IsEnabled) return null; AnnounceIfDisabled(); var n = Interlocked.Increment(ref _refused); if (n == 1 || n % 100 == 0) _logger.LogWarning("[MdpOutboundGate] {Message};已拦截 {Count} 次", DisabledMessage, n); return MdpPushResult.Hold(DisabledMessage); } }