I have a lambda function that is triggered by SQS, but it seems that SQS triggered it multiple times even when the operation is succeeded. Here are some of my code
// handle.ts to handle sqs
exports.handler = async function (event, context, callback) {
// SQS may invoke with multiple messages
for (const message of event.Records) {
// make the call to a service
runAsyncService(message.body)
}
// ran all async call all together
return callback(null, "succeed")
};
using those handler, seems that the request is triggered 3 times (configureable but it reaches the max retries) each with different RequestId (which some said, it indicated that the request was timed out). Then I had this code that fixes the issue of multiple triggers.
// new handle.ts to handle sqs event
exports.handler = async function (event, context, callback) {
let jobs: any = [] // hold all async call
// SQS may invoke with multiple messages
for (const message of event.Records) {
// make the call to a service
jobs.push(runAsyncService(message.body))
}
// ran all async call all together
return Promise.all(jobs)
.then(() => {
console.log(`All ${jobs.length} job(s) finished`)
return context.succeed('Finished')
})
};
as you may see that I used Promise.all() function to ran all the async call, then called context.succeed(), using this had the side effect, if there are multiple Records from sqs, if any one of the task is failed the all the promise will be failed even when the other are successful. Calling context.succeed() inside the loop also not an option because it also triggered the call multiple times. The only option I had in mind right now is limiting the batch size to 1 but I don't really like the idea. Also I used getlift/lift to configure sqs and lambda together. Do you guys have any suggestion for me? thanks.