Trigger function with a delay longer than an hour in a Node/Express app
I would like to trigger a function in my express app with a delay of 1 hour or 5 hours after a specific endpoint was called.
I've tried using a simple setTimeout
in the then
chain of my enpoint with something like this in my controller:
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
})
})
})
and seems to work but I have two main dubts:
- If I restart the pm2 process of my application with (pm2 startOrReload prod.json), all the timeouts are cancelled?
- If I have something like 600 timeouts scheduled with this system can I have any performance issues?
Any experience with something like this?
node.js express promise settimeout
add a comment |
I would like to trigger a function in my express app with a delay of 1 hour or 5 hours after a specific endpoint was called.
I've tried using a simple setTimeout
in the then
chain of my enpoint with something like this in my controller:
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
})
})
})
and seems to work but I have two main dubts:
- If I restart the pm2 process of my application with (pm2 startOrReload prod.json), all the timeouts are cancelled?
- If I have something like 600 timeouts scheduled with this system can I have any performance issues?
Any experience with something like this?
node.js express promise settimeout
1
You should probably consider some sort of dedicated queue for this, like kue.
– robertklep
Nov 19 '18 at 13:06
seems a good choice, thanks for the suggestion
– lellefood
Nov 19 '18 at 14:22
At the end I decided to use kue to manage jobs and delay them
– lellefood
Dec 4 '18 at 9:18
add a comment |
I would like to trigger a function in my express app with a delay of 1 hour or 5 hours after a specific endpoint was called.
I've tried using a simple setTimeout
in the then
chain of my enpoint with something like this in my controller:
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
})
})
})
and seems to work but I have two main dubts:
- If I restart the pm2 process of my application with (pm2 startOrReload prod.json), all the timeouts are cancelled?
- If I have something like 600 timeouts scheduled with this system can I have any performance issues?
Any experience with something like this?
node.js express promise settimeout
I would like to trigger a function in my express app with a delay of 1 hour or 5 hours after a specific endpoint was called.
I've tried using a simple setTimeout
in the then
chain of my enpoint with something like this in my controller:
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
})
})
})
and seems to work but I have two main dubts:
- If I restart the pm2 process of my application with (pm2 startOrReload prod.json), all the timeouts are cancelled?
- If I have something like 600 timeouts scheduled with this system can I have any performance issues?
Any experience with something like this?
node.js express promise settimeout
node.js express promise settimeout
asked Nov 19 '18 at 12:58
lellefood
127121
127121
1
You should probably consider some sort of dedicated queue for this, like kue.
– robertklep
Nov 19 '18 at 13:06
seems a good choice, thanks for the suggestion
– lellefood
Nov 19 '18 at 14:22
At the end I decided to use kue to manage jobs and delay them
– lellefood
Dec 4 '18 at 9:18
add a comment |
1
You should probably consider some sort of dedicated queue for this, like kue.
– robertklep
Nov 19 '18 at 13:06
seems a good choice, thanks for the suggestion
– lellefood
Nov 19 '18 at 14:22
At the end I decided to use kue to manage jobs and delay them
– lellefood
Dec 4 '18 at 9:18
1
1
You should probably consider some sort of dedicated queue for this, like kue.
– robertklep
Nov 19 '18 at 13:06
You should probably consider some sort of dedicated queue for this, like kue.
– robertklep
Nov 19 '18 at 13:06
seems a good choice, thanks for the suggestion
– lellefood
Nov 19 '18 at 14:22
seems a good choice, thanks for the suggestion
– lellefood
Nov 19 '18 at 14:22
At the end I decided to use kue to manage jobs and delay them
– lellefood
Dec 4 '18 at 9:18
At the end I decided to use kue to manage jobs and delay them
– lellefood
Dec 4 '18 at 9:18
add a comment |
3 Answers
3
active
oldest
votes
Timeout like this might be a solution but not the very best kind.
If timeouts are instantly adding to your memory, like every hour, when you restart your Node.js process the timers yet to trigger are lost, and that means you can not restart your App even when you are trying to update the new code if you don't want to lose any of them. Losing emails or never restart, a little bit of confusion, right?
The most frequently implemented approach for such a case is Message Queue.
You can take Message Queue as timers that stored and consumed in a database, so you don't have to worry about whether timers are canceled or called multiple times when you don't want that happen.
RabbitMQ is a standalone MQ that is friendly to Node.js.
Kue is an MQ-like NPM package that relies on Redis.
Hope you like'em. ;)
add a comment |
I already faced this issue.
The solution I found is to use my database as the time register.
Basically, if you are using SQL or Document oriented database:
- Insert a scheduled action into the database.
- Check every x seconds (depend on the accuracy you need) if there is an entry which need to be popped. If so, delete the item, take it, execute it.
You could also use cron
package to do the check, but... since this is simple to be implemented, you should do it by yourself.
EDIT: Why this solution?
First, this is RAM saver for server, when you have like 5000 entries, you don't have to store it in the memory.
add a comment |
- Yes all your timeout will be cancelled as they are memory stored
- i don't think having 600 timeout might be an issue but you may find better suitable method like having an array with all your timeouts sorted and a setInterval to check if there's a need to execute something.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53375170%2ftrigger-function-with-a-delay-longer-than-an-hour-in-a-node-express-app%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Timeout like this might be a solution but not the very best kind.
If timeouts are instantly adding to your memory, like every hour, when you restart your Node.js process the timers yet to trigger are lost, and that means you can not restart your App even when you are trying to update the new code if you don't want to lose any of them. Losing emails or never restart, a little bit of confusion, right?
The most frequently implemented approach for such a case is Message Queue.
You can take Message Queue as timers that stored and consumed in a database, so you don't have to worry about whether timers are canceled or called multiple times when you don't want that happen.
RabbitMQ is a standalone MQ that is friendly to Node.js.
Kue is an MQ-like NPM package that relies on Redis.
Hope you like'em. ;)
add a comment |
Timeout like this might be a solution but not the very best kind.
If timeouts are instantly adding to your memory, like every hour, when you restart your Node.js process the timers yet to trigger are lost, and that means you can not restart your App even when you are trying to update the new code if you don't want to lose any of them. Losing emails or never restart, a little bit of confusion, right?
The most frequently implemented approach for such a case is Message Queue.
You can take Message Queue as timers that stored and consumed in a database, so you don't have to worry about whether timers are canceled or called multiple times when you don't want that happen.
RabbitMQ is a standalone MQ that is friendly to Node.js.
Kue is an MQ-like NPM package that relies on Redis.
Hope you like'em. ;)
add a comment |
Timeout like this might be a solution but not the very best kind.
If timeouts are instantly adding to your memory, like every hour, when you restart your Node.js process the timers yet to trigger are lost, and that means you can not restart your App even when you are trying to update the new code if you don't want to lose any of them. Losing emails or never restart, a little bit of confusion, right?
The most frequently implemented approach for such a case is Message Queue.
You can take Message Queue as timers that stored and consumed in a database, so you don't have to worry about whether timers are canceled or called multiple times when you don't want that happen.
RabbitMQ is a standalone MQ that is friendly to Node.js.
Kue is an MQ-like NPM package that relies on Redis.
Hope you like'em. ;)
Timeout like this might be a solution but not the very best kind.
If timeouts are instantly adding to your memory, like every hour, when you restart your Node.js process the timers yet to trigger are lost, and that means you can not restart your App even when you are trying to update the new code if you don't want to lose any of them. Losing emails or never restart, a little bit of confusion, right?
The most frequently implemented approach for such a case is Message Queue.
You can take Message Queue as timers that stored and consumed in a database, so you don't have to worry about whether timers are canceled or called multiple times when you don't want that happen.
RabbitMQ is a standalone MQ that is friendly to Node.js.
Kue is an MQ-like NPM package that relies on Redis.
Hope you like'em. ;)
answered Nov 19 '18 at 13:54
YLS
57038
57038
add a comment |
add a comment |
I already faced this issue.
The solution I found is to use my database as the time register.
Basically, if you are using SQL or Document oriented database:
- Insert a scheduled action into the database.
- Check every x seconds (depend on the accuracy you need) if there is an entry which need to be popped. If so, delete the item, take it, execute it.
You could also use cron
package to do the check, but... since this is simple to be implemented, you should do it by yourself.
EDIT: Why this solution?
First, this is RAM saver for server, when you have like 5000 entries, you don't have to store it in the memory.
add a comment |
I already faced this issue.
The solution I found is to use my database as the time register.
Basically, if you are using SQL or Document oriented database:
- Insert a scheduled action into the database.
- Check every x seconds (depend on the accuracy you need) if there is an entry which need to be popped. If so, delete the item, take it, execute it.
You could also use cron
package to do the check, but... since this is simple to be implemented, you should do it by yourself.
EDIT: Why this solution?
First, this is RAM saver for server, when you have like 5000 entries, you don't have to store it in the memory.
add a comment |
I already faced this issue.
The solution I found is to use my database as the time register.
Basically, if you are using SQL or Document oriented database:
- Insert a scheduled action into the database.
- Check every x seconds (depend on the accuracy you need) if there is an entry which need to be popped. If so, delete the item, take it, execute it.
You could also use cron
package to do the check, but... since this is simple to be implemented, you should do it by yourself.
EDIT: Why this solution?
First, this is RAM saver for server, when you have like 5000 entries, you don't have to store it in the memory.
I already faced this issue.
The solution I found is to use my database as the time register.
Basically, if you are using SQL or Document oriented database:
- Insert a scheduled action into the database.
- Check every x seconds (depend on the accuracy you need) if there is an entry which need to be popped. If so, delete the item, take it, execute it.
You could also use cron
package to do the check, but... since this is simple to be implemented, you should do it by yourself.
EDIT: Why this solution?
First, this is RAM saver for server, when you have like 5000 entries, you don't have to store it in the memory.
answered Nov 19 '18 at 13:06


Izio
1949
1949
add a comment |
add a comment |
- Yes all your timeout will be cancelled as they are memory stored
- i don't think having 600 timeout might be an issue but you may find better suitable method like having an array with all your timeouts sorted and a setInterval to check if there's a need to execute something.
add a comment |
- Yes all your timeout will be cancelled as they are memory stored
- i don't think having 600 timeout might be an issue but you may find better suitable method like having an array with all your timeouts sorted and a setInterval to check if there's a need to execute something.
add a comment |
- Yes all your timeout will be cancelled as they are memory stored
- i don't think having 600 timeout might be an issue but you may find better suitable method like having an array with all your timeouts sorted and a setInterval to check if there's a need to execute something.
- Yes all your timeout will be cancelled as they are memory stored
- i don't think having 600 timeout might be an issue but you may find better suitable method like having an array with all your timeouts sorted and a setInterval to check if there's a need to execute something.
answered Nov 19 '18 at 13:09
davidonet
574314
574314
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53375170%2ftrigger-function-with-a-delay-longer-than-an-hour-in-a-node-express-app%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
You should probably consider some sort of dedicated queue for this, like kue.
– robertklep
Nov 19 '18 at 13:06
seems a good choice, thanks for the suggestion
– lellefood
Nov 19 '18 at 14:22
At the end I decided to use kue to manage jobs and delay them
– lellefood
Dec 4 '18 at 9:18