💬 Что из себя представляет паттерн Throttle, применяемый в облачной разработке?



Паттерн Throttle (Дроссельная заслонка) ограничивает частоту вызовов функции некоторым предельным числом вызовов в единицу времени.



📌 Например:

◆ пользователю может быть разрешено обращаться к сервису не чаще, чем 10 раз в секунду;

◆ клиенту может быть позволено вызывать определенную функцию только один раз в каждые 500 миллисекунд;

◆ учетной записи может быть разрешено только три неудачные попытки входа в систему в течение 24 часов.



Наиболее распространенной причиной применения Throttle является устранение резких всплесков активности, способных привести к насыщению системы необоснованным количеством дорогостоящих запросов, которые могут привести к ухудшению качества обслуживания и в конечном итоге к отказу. Система может поддерживать автоматическое масштабирование для удовлетворения потребностей пользователей, но на это требуется время, и система может быть не в состоянии реагировать достаточно быстро.



📌 Компоненты:



Effector — функция, частоту вызовов которой нужно ограничить.

Throttle — функция, принимающая Effector и возвращающая замыкание с той же сигнатурой, что и Effector.



📌 Пример кода:



type Effector func(context.Context) (string, error)



func Throttle(e Effector, max uint, refill uint, d time.Duration) Effector {

var tokens = max

var once sync.Once



return func(ctx context.Context) (string, error) {

if ctx.Err() != nil {

return "", ctx.Err()

}



once.Do(func() {

ticker := time.NewTicker(d)



go func() {

defer ticker.Stop()



for {

select {

case <-ctx.Done():

return



case <-ticker.C:

t := tokens + refill

if t > max {

t = max

}

tokens = t

}

}

}()

})

if tokens <= 0 {

return "", fmt.Errorf("too many calls")

}

tokens--



return e(ctx)

}

}