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);
}
}