First: If you declare your handler async then you can’t use callback to callback to send the response. You need to return { lesson, success: true };
Second: Your Lambdas need to be idempotent because they may be executed multiple times with the same input. This is baked into the basic execution model which guarantees a Lambda will be executed at least once.
I think you’re main problem here is using async and callback. The async handler syntax with Node 8.10 doesn’t include the callback parameter. Using return should solve the bulk of your problem.
Pure functions don’t have side effects like network calls.
Being idempotent is not the same as being pure.
For example: I could have a Lambda that creates a record in DynamoDB. If the Lambda generates a random string for the key then it’s not idempotent because subsequent calls with the same event will result in multiple records being added to DynamoDB but if I have a consistent way to generate the key (perhaps using an ID included in the event) so only one record is ever created and I always return success even if the record already exists then I’m idempotent.
Cool thanks man for all the explanation. I deployed the new version. Let’s see how that works this Sunday. I’ll post the updates if it works or if it doesn’t
Also, if I can store the data in DynamoDB then I can make a boolean to not run Lambda the 2nd time
By default, runCron = true
On 1st run, it runs the cron & make runCron = false
On 2nd run, its runCron = false then don’t run it. Can I do this in Lambda?
Currently, it runs twice every Sunday (10:00 am & 10:01 am UTC)
A Lambda being executed multiple times for a single event should be very rare. If the async/callback change fixes your problem and the occasional duplicate message isn’t a problem then personally I wouldn’t worry about making the Lambda fully idempotent.
Can you simplify the function by removing the lines with await to confirm that it only runs once?
exports.run = async (event, context) => {
const time = new Date();
console.log(`Your cron function "${context.functionName}" ran at ${time}`);
console.log("event ", event);
return { message: "success" };
};
If it still executes multiple times are they for the same event?
If it works then is it possible your function is timing out during the first execution? Try adding each of the lines with await one at a time to see if it still only triggers once. The CloudWatch logs can also tell you this.
If your function is timing out then increase the timeout.
Are you sure the service only scheduled once? Check CloudWatch to make sure you don’t have two accidentally scheduled - perhaps in a different stage or region?