Функция запуска с задержкой более часа в приложении Node / Express - PullRequest
0 голосов
/ 19 ноября 2018

Я хотел бы вызвать функцию в моем экспресс-приложении с задержкой в ​​1 час или 5 часов после вызова конкретной конечной точки.

Я пытался использовать простой setTimeout в then цепочка моей цели с чем-то вроде этого в моем контроллере:

function(req, res, next) {

  return mailer.sendEmail(req.user, 'firstEmail') // returns a promise
  .then(function(emailResult) {
    if (emailResult == 'ok') {
       res.sendStatus(200).json({ message: 'You will receive an email in 1 hour' }) // set positive API json response
    } else {
       res.sendStatus(200).json({ message: 'You will receive an email in 5 hour' }) // set negative API json response
    }
    return emailResult
  })
  .then(function(emailResult){
    return new Promise((resolve, reject) => {
        setTimeout(function(){
            return return mailer.sendEmail(req.user, 'secondEmail')
        }, emailResult == 'ok' ? 60 * 60 * 1000 : 5 * 60 * 60 * 1000) // 1 hour or 5 hours
    })
  }) 
})

и, кажется, работает, но у меня есть два основных дублирования:

  • Если я перезапущу процесс pm2 моегоприложение с (pm2 startOrReload prod.json), все таймауты отменены?
  • Если у меня запланировано около 600 тайм-аутов, запланированных с этой системой, могу ли я иметь какие-либо проблемы с производительностью?

Любыеопыт с чем-то вроде этого?

Ответы [ 3 ]

0 голосов
/ 19 ноября 2018
  • Да, все ваши тайм-ауты будут отменены, так как они хранятся в памяти
  • Я не думаю, что 600-тайм-аут может быть проблемой, но вы можете найти более подходящий метод, такой как наличие массива со всеми вашимиотсортированные тайм-ауты и setInterval для проверки необходимости выполнения чего-либо.
0 голосов
/ 19 ноября 2018

Тайм-аут, как это, может быть решением, но не самым лучшим.

Если тайм-ауты мгновенно добавляются в вашу память, как каждый час, когда вы перезапускаете процесс Node.js, таймеры, которые еще должны быть активированы,потерян, и это означает, что вы не можете перезапустить приложение, даже если вы пытаетесь обновить новый код, если вы не хотите потерять какой-либо из них.Потеря электронной почты или перезапуск, небольшая путаница, верно?

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

RabbitMQ - этоавтономный MQ, дружественный к Node.js.

Kue - это MQ-подобный пакет NPM, основанный на Redis.

Надеюсь, вам понравится их.;)

0 голосов
/ 19 ноября 2018

Я уже сталкивался с этой проблемой.

Решение, которое я нашел, заключается в использовании моей базы данных в качестве регистра времени. В основном, если вы используете базу данных, ориентированную на SQL или документ:

  1. Вставка запланированного действия в базу данных.
  2. Проверяйте каждые x секунд (в зависимости от необходимой точности), есть ли запись, которую нужно вытолкнуть. Если это так, удалите элемент, возьмите его, выполните его.

Вы также можете использовать пакет cron для проверки, но ... поскольку это легко реализовать, вы должны сделать это самостоятельно.

РЕДАКТИРОВАТЬ: Почему это решение?

Во-первых, это экономия ОЗУ для сервера, когда у вас около 5000 записей, вам не нужно хранить ее в памяти.

...