Самый эффективный способ запускать функцию каждый раз, когда заканчивается таймер, но с большим количеством таймеров (тысячи/миллионы)

Я запускаю службу, в которой пользователи загружают продолжительность, и функция должна многократно выполняться каждый раз, когда таймер истекает.

Например, пользователь говорит «Выполнять каждые 5 минут», а затем эту функцию нужно запускать каждые 5 минут. Это делается через API.

Для небольшого количества таймеров это тривиально:

func doEvery(d time.Duration, f func(time.Time)) {
    for x := range time.Tick(d) {
        f(x) // Run the function every d duration
    }
}

Я могу запускать каждый таймер в горутине, и это прекрасно работает. Я могу запускать и останавливать все с помощью некоторых базовых функций WaitGroups и синхронизации.

Но что, если у меня есть тысячи или миллионы таймеров? Я могу создать горутину для каждого из них, но это кажется очень неэффективным. Это не Эрланг.

Должен ли я иметь несколько рабочих очередей, отсортированных по «задержке», и просто выделять больше рабочих для более частых функций? Если таймер не готов, он снова ставится в очередь.

Это также не идеально, потому что рабочие заняты ожиданием (выходят, проверяют время, помещают в очередь), а не блокируются, пока не закончится следующий таймер.

Может быть, я мог бы иметь какую-то карту, проиндексированную оставшейся продолжительностью? Я не уверен, какой лучший подход здесь.

Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
1
0
48
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Недавно я создал такое решение, в котором пользователь получает уведомление в зависимости от настроек интервала. Я делаю модель рабочего пула, используя rabbitMQ и два скрипта go. Где скрипт one go использует нижеприведенный модуль cron для создания заданий в очереди сообщений

https://github.com/robfig/cron

Другой скрипт go — это рабочий скрипт, использующий очередь сообщений и выполняющий действия. Для масштабирования я запускаю несколько экземпляров рабочего скрипта. Автомасштабирование рабочего скрипта можно сделать по количеству сообщений в rabbitMQ

Другие вопросы по теме