1
votes

Most likely silly question but couldn't find the clear answer for Lambda behavior I'm seeing.
I've created the simplest possible Lambda function that put dummy records into DynamoDB table (in synchronous way):

const AWS = require('aws-sdk');
var docClient = new AWS.DynamoDB.DocumentClient();

exports.handler = async (event, context) => {
    var myTable = 'my-secret-table-name';
    
    var i;
    for(i=0; i<10; i++){
        var params = {
            TableName:myTable,
            Item:{
                PK: i.toString(),
                SK: 'whatever'
                
            }
        };
                        
        await docClient.put(params, function(err, data) {
            if (err) {
                console.error("Error inserting to a table ", JSON.stringify(err, null, 2));
            } else {
                console.log("Insert successfull. Run: "+ i);
            }
        }).promise();
    }
    
    return "Success";
};

it works perfectly and required records are inserted to DynamoDB table. But when I look at lambda logs i see below:

2020-11-18 21:57:06.674 Insert successfull. Run: 0
2020-11-18 21:57:06.696 Insert successfull. Run: 1
2020-11-18 21:57:06.773 Insert successfull. Run: 1
2020-11-18 21:57:06.775 Insert successfull. Run: 2
2020-11-18 21:57:06.856 Insert successfull. Run: 2
2020-11-18 21:57:06.875 Insert successfull. Run: 3
2020-11-18 21:57:06.933 Insert successfull. Run: 3
2020-11-18 21:57:06.936 Insert successfull. Run: 4
2020-11-18 21:57:07.012 Insert successfull. Run: 4
2020-11-18 21:57:07.054 Insert successfull. Run: 5
2020-11-18 21:57:07.153 Insert successfull. Run: 5
2020-11-18 21:57:07.156 Insert successfull. Run: 6
2020-11-18 21:57:07.433 Insert successfull. Run: 6
2020-11-18 21:57:07.513 Insert successfull. Run: 7
2020-11-18 21:57:07.567 Insert successfull. Run: 7
2020-11-18 21:57:07.594 Insert successfull. Run: 8
2020-11-18 21:57:07.645 Insert successfull. Run: 8
2020-11-18 21:57:07.693 Insert successfull. Run: 9
2020-11-18 21:57:07.747 Insert successfull. Run: 9

Not matter how many times I run the function, I always got each `putItem` executed twice. I'm aware that lambda guarantee "at-least-once" processing but shouldn't it at least sometimes executed once instead always twice?
And if "at-least-once" processing is the reason than why "Run 0" is executed once and all other are executed twice?
Explanation would be appreciated. Although in this specific case executing `putItem` doesn't change much, in more complex case I'm developing it starts to cause me some trouble and I don't know should I accept that or my code is just crappy.
Regards!
1

1 Answers

2
votes

It is actually being executed twice because you are using multiple conflicting ways to resolve the async call to DynamoDB:

  • You have an inline callback function that will be executed once the execution result is ready.
  • You also use the promise() function

Both lead to an execution of the call. It should be resolved if you either remove the call of promise() or the callback function.

Please have a look at Getting to know asynchronous JavaScript: Callbacks, Promises and Async/Await to learn more about the differences and similarities between the different methods.