0:00
[БЕЗ_ЗВУКА] Ну, и напоследок поговорим про rate-лимиты.
Довольно часто бывает так, что нам нужно каким-либо образом затормозить нашу
программу, например, в зависимости от утилизации процессора,
либо дисковой подсистемы, нам нужно уменьшить нагрузки на эти части.
В Go мы можем организовать это, используя буферизированные каналы.
Прежде чем мы будем смотреть код, давайте посмотрим, как это выглядит визуально.
Смотрите.
Мы запустили пять горутин, которые выполняют по шесть операций.
И при этом наш rate-лимит — это 2.
Посмотрите, как стройно выходит.
Сначала горутины за номером 0 и 1 выполняются,
после этого горутины за номером 2 и 3,
и после этого горутина за номером 4.
А теперь давайте смотреть код.
Создаем WaitGroup, для того чтобы контролировать работу горутин.
После этого основная тема данного видео — это канал с квотой.
Канал с квотой — это буферизированный канал,
где размер буфера как раз и является нашим лимитом.
Мы создали канал просто из пустых структур, хотя тут ничего не мешает,
чтобы быть...
Просто пустая структура.
Не занимает никакого места.
Ну, дальше мы передаем канал с квотой уже в наш Worker,
который выполняется в отдельной горутине.
А что происходит в Worker'е?
Смотрите, прежде чем вообще начать
выполнять какую-то полезную работу, Worker пытается взять слот на эту работу.
В данном случае мы пытаемся положить пустую структуру в канал.
Если в канале уже лежат,
то есть если буфер канала уже заполнен, значит,
уже два Worker'а работают, то есть уже два места заняты, там уже лежит две структуры.
И мы блокируемся, до тех пор пока там не освободится место.
Таким образом мы не позволяем расти сверх квоты.
После этого мы выполняем уже непосредственно нашу работу.
В данном случае это просто печать результата какого-то текста,
ну и даем возможность поработать другим горутинам.
После этого мы опускаем квоту, то есть возвращаем слот на работу.
Все свое мы закончили.
Это значит, что мы теперь читаем из этого канала,
то есть мы освобождаем там место, для того чтобы какая-то
другая горутина положила туда свой слот в этот канал.
Вот.
Теперь давайте немножко изменим нашу программу,
для того чтобы возвращать квоту обратно на каждой второй итерации.
Раскомментируем этот блок.
И посмотрим, как изменилась наша программа.
Смотрите, если
раньше мы выполняли
все итерации только двух горутин подряд, например, вот так,
то теперь у нас стало работать немножко по-другому, теперь у нас более плавно.
Смотрите.
Выполнилось по две итерации от одной части горутин,
по две итерации от другой, по две итерации от третьей и так далее.
То есть теперь Worker не полностью
захватывает квоту и выполняет всю свою работу до конца,
но он дает возможность выполнять ее каким-то другим Worker'ам,
то есть делится, скажем так, пропускной способностью, ресурсами вашей программы.
При этом обратите внимание, что по-прежнему выполняются наши условия
rate-лимита, чтобы одновременно работало не более двух горутин.
Это довольно мощный механизм.
Пользуйтесь им.