using TarninaHub.Application.Matchmaking;
namespace TarninaHub.Infrastructure.Llm;
///
/// In-memory sliding-window request limiter (per instance) for LLM cost control.
///
public sealed class InMemoryLlmRequestLimiter : ILlmRequestLimiter
{
private readonly int _maxPerWindow;
private readonly TimeSpan _window;
private readonly Queue _timestamps = new();
private readonly Lock _gate = new();
public InMemoryLlmRequestLimiter(int maxRequestsPerMinute, TimeSpan? window = null)
{
_maxPerWindow = Math.Max(1, maxRequestsPerMinute);
_window = window ?? TimeSpan.FromMinutes(1);
}
public bool TryAcquire()
{
var now = DateTimeOffset.UtcNow;
lock (_gate)
{
while (_timestamps.Count > 0 && now - _timestamps.Peek() > _window)
{
_timestamps.Dequeue();
}
if (_timestamps.Count >= _maxPerWindow)
{
return false;
}
_timestamps.Enqueue(now);
return true;
}
}
}