using System.Collections.Concurrent; namespace molilian.core { public static class SpecialBusinessRateLimiter { private static readonly ConcurrentDictionary States = new(); public static bool TryAcquire(string bucketKey, int limit, TimeSpan window) { if (string.IsNullOrWhiteSpace(bucketKey)) return true; if (limit <= 0 || window <= TimeSpan.Zero) return true; var state = States.GetOrAdd(bucketKey, _ => new SlidingWindowState()); var nowTicks = DateTime.UtcNow.Ticks; var minTicks = nowTicks - window.Ticks; lock (state.SyncRoot) { while (state.Timestamps.Count > 0 && state.Timestamps.Peek() < minTicks) { state.Timestamps.Dequeue(); } if (state.Timestamps.Count >= limit) { return false; } state.Timestamps.Enqueue(nowTicks); return true; } } private sealed class SlidingWindowState { public object SyncRoot { get; } = new(); public Queue Timestamps { get; } = new(); } } }