Реализуйте двухстадийный конвейер. Стадия 1 поставляет userIDs. Стадия 2
опрашивает внешний API функцией callAPI(id) в workers воркерах, но
суммарный темп вызовов callAPI не должен превышать rps запросов в секунду
по всему пулу.
// RunRateLimited: стадия 1 даёт userIDs; стадия 2 опрашивает API в `workers`
// воркерах, но суммарный темп вызовов callAPI не превышает rps запросов/сек.
func RunRateLimited(userIDs []int, workers, rps int, callAPI func(id int) string) []string
Требования:
- Все
userIDs обрабатываются ровно один раз, результаты callAPI
возвращаются (порядок не важен).
- Не более
rps вызовов callAPI в любую секунду по всему пулу воркеров.
- Параллелизм до
workers одновременных вызовов callAPI.
- Реализовать вручную (например,
time.Ticker как общий лимитер) без
сторонних библиотек.
На что смотрит интервьюер:
- Общий на весь пул лимитер (тикер с интервалом
time.Second/rps), который
гейтит каждый вызов callAPI, а не отдельный лимит на воркера.
- Конвейер из двух стадий: раздача
userIDs через канал и пул воркеров.
- Корректный сбор результатов без гонок (mutex или канал), отсутствие утечек
горутин под
-race.
- Нижняя граница по времени соблюдается:
N задач при rps не успевают
выполниться быстрее, чем за ~N/rps секунд.