We cannot assume that a Lambda container will hold state in case of failure/timeout. AWS controls its container in an unpredictable way, hence we need to assume that it is stateless. Thus, the workaround implemented in the lambda.js
file would not work very well when the container is not properly reused, leading us to undesired side-effects.
Here is the log output, showing that, in case of an retry-attempt, the execution wasn't droped, causing the system to execute it twice.
var http = require('http');
var lastReqId;
console.log('Loading function');
exports.handler = (event, context, callback) => {
console.log('Starting function');
// We check if the lambda is being retried.
// If that's the case, we kill it
// We leverage lambda's quirks:
// - lambda's node process reuse which keeps vars instanced
// - retried lambdas have the same request id
// Hopefully Amz will someday allow us to disable autoretries
console.log("lastReqId: "+lastReqId)
console.log("context.awsRequestId: "+context.awsRequestId)
if ( lastReqId == context.awsRequestId ) {
console.log('Lambda auto retry detected. Aborting.');
return context.succeed();
} else {
console.log('Not a retry. Running call.');
lastReqId = context.awsRequestId;
}
var optionspost = {
host: 'example.com',
port:80,
path: '/execute/job',
method: 'POST'
};
var req = http.request(optionspost, function(res) {
console.log('Success, with: ' + res.statusCode);
context.succeed();
}).on('error', function (err) {
console.log('Error, with: ' + err.message);
context.done("Failed");
});
req.write("");
req.end();
console.log('End function');
};