Reputation: 365
I'm creating a google cloud function that sends a daily email to users but the function is only invoked first time after deployment and then always fails with timeout even after 300 seconds (In general it takes 10 - 15 seconds to execute).
The function is doing DB finds, for loops and if conditions, so I think it's a problem of request / response from the app so it's prevent future invokation. Can you please help me modify the code below.
app.get('/emails', function(req, res){
var books = [];
Book.find({}, (err, res) => {
if (err) {
return err;
}
books = res;
}).catch(err => console.log(err))
User.find({}, (err, users) => {
if (err) {
return err;
}
const uniques = users.filter(
(v, i, a) => a.findIndex((t) => t.ID === v.ID) === i
);
for(var i =0; i < uniques.length; i++) {
var count = 0;
for (var j = 0; j < books.length; j++) {
if (books[j].UserID === uniques[i].ID && books[j].State === "OK") {
count += 1;
}
}
var EmailPayload = {
// nodemailer object here
}
if (count > 0) {
Email.sendEmailIndex(EmailPayload);
}
}
}).catch(err => {
console.log(err)
})
});
Upvotes: 0
Views: 122
Reputation: 2592
The function is being invoked by GET /emails which expects a response. Without a response, the function will keep running until it times out because Google doesn't know it finished.
To fix this, conclude with a basic 200 after the script is done. It's also sensible to respond in case of failure to cover all cases and make sure there's always a response sent back.
app.get('/emails', function(req, res) {
var books = [];
Book.find({}, (err, res) => {
if (err) {
return err;
}
books = res;
return User.find({}, (err, users) => {
if (err) {
return err;
}
const uniques = users.filter(
(v, i, a) => a.findIndex((t) => t.ID === v.ID) === i
);
for (var i = 0; i < uniques.length; i++) {
var count = 0;
for (var j = 0; j < books.length; j++) {
if (books[j].UserID === uniques[i].ID && books[j].State === "OK") {
count += 1;
}
}
var EmailPayload = {
// nodemailer object here
}
if (count > 0) {
Email.sendEmailIndex(EmailPayload);
}
}
// Send a response to conclude function execution
res.status(200).send({
message: 'Emails sent'
});
});
}).catch(err => {
console.log(err);
// Send a response to conclude function execution
res.status(500).send({
message: 'Failed to send emails',
error: err
});
})
});
Upvotes: 2