Ограничить доступ к ресурсу

Мне интересно, как реализовать оболочку для службы REST, которая нуждается в регулировании. Стоимость услуги ограничена, например, "Макс. 60 звонков в минуту" или подобным. Чрезмерное использование ресурса означает, что мой клиент заблокирован на длительное время, поэтому я должен позаботиться о том, чтобы этого не произошло, поэтому я бы хотел, чтобы сама оболочка была ограничена по скорости.

Изменить: удалил окончательную идею и опубликовал в качестве ответа

1 ответ

Решение

Отвечая на мой собственный вопрос, вдохновленный комментарием @Alex, этот вопрос решает проблему максимального числа N запросов за промежуток времени T. Он содержит время последних N запросов в списке (циклический буфер) и разрешает запрос, если самый старый звонок был старше Т.

public class Throttler<T>
{
   private readonly long[] callTimes;
   private int cur;      
   private readonly Func<T> func;
   private readonly TimeSpan interval;
   private readonly object padlock = new object();    

   public Throttler(Func<T> func, int maxCalls, TimeSpan interval)
   {
      this.func = func;
      callTimes = new long[maxCalls];
      this.interval = interval;
      cur = 0;
   }

   public T Call()
   {
      lock (padlock)
      {
         do
         {
            long oldestCall = callTimes[(cur + 1)%callTimes.Length];
            long now = DateTime.UtcNow.Ticks;               
            if (now - oldestCall > interval.Ticks)
            {                 
               cur = (cur + 1) % callTimes.Length;                  
               callTimes[cur] = now;
               return func();
            }
            int sleepTime = (int)((interval.Ticks - (now - oldestCall))/TimeSpan.TicksPerMillisecond) + 1;               
            Thread.Sleep(sleepTime);               
         } while (true);
      }
   }
}
Другие вопросы по тегам