using System; using System.Collections.Generic; using Lskj.CommandKernel; namespace Lskj.AgentBridge { public sealed class InMemoryPlanStore : IServerPlanStore { public const int MaximumPlans = 128; private readonly object _syncRoot = new object(); private readonly Dictionary _plans = new Dictionary(StringComparer.OrdinalIgnoreCase); public void Save(CommandPlan plan) { if (plan == null) throw new ArgumentNullException("plan"); if (string.IsNullOrWhiteSpace(plan.PlanId)) throw new ArgumentException("计划 ID 不能为空。", "plan"); lock (_syncRoot) { if (!_plans.ContainsKey(plan.PlanId) && _plans.Count >= MaximumPlans) throw new CommandKernelException( "plan_store_capacity_exceeded", "ERP 待执行计划已达到安全上限,请等待旧计划过期后重试。", 6); _plans[plan.PlanId] = plan; } } public bool TryGet(string planId, out CommandPlan plan) { if (string.IsNullOrWhiteSpace(planId)) { plan = null; return false; } lock (_syncRoot) { return _plans.TryGetValue(planId, out plan); } } public void Remove(string planId) { if (string.IsNullOrWhiteSpace(planId)) return; lock (_syncRoot) { _plans.Remove(planId); } } public void PurgeExpired(DateTime utcNow) { lock (_syncRoot) { List expired = new List(); foreach (KeyValuePair item in _plans) { if (item.Value == null || item.Value.ExpiresAtUtc < utcNow) expired.Add(item.Key); } foreach (string planId in expired) _plans.Remove(planId); } } } }