44 lines
1.2 KiB
C#
44 lines
1.2 KiB
C#
// Archivo: Elecciones.Infrastructure/Services/RateLimiterService.cs
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Elecciones.Infrastructure.Services;
|
|
|
|
public class RateLimiterService
|
|
{
|
|
private readonly SemaphoreSlim _semaphore;
|
|
private readonly int _limit;
|
|
private readonly TimeSpan _period;
|
|
private Timer _timer;
|
|
|
|
public RateLimiterService(int limit, TimeSpan period)
|
|
{
|
|
_limit = limit;
|
|
_period = period;
|
|
_semaphore = new SemaphoreSlim(limit, limit);
|
|
|
|
// Un temporizador que "rellena el cubo" cada 5 minutos.
|
|
_timer = new Timer(
|
|
callback: _ => RefillBucket(),
|
|
state: null,
|
|
dueTime: period,
|
|
period: period);
|
|
}
|
|
|
|
private void RefillBucket()
|
|
{
|
|
// Calcula cuántas fichas faltan en el cubo.
|
|
var releaseCount = _limit - _semaphore.CurrentCount;
|
|
if (releaseCount > 0)
|
|
{
|
|
// Añade las fichas que faltan.
|
|
_semaphore.Release(releaseCount);
|
|
}
|
|
}
|
|
|
|
// El método que usarán nuestras tareas para "pedir una ficha".
|
|
public async Task WaitAsync(CancellationToken cancellationToken = default)
|
|
{
|
|
await _semaphore.WaitAsync(cancellationToken);
|
|
}
|
|
} |