BLACKMAMBA
BLACKMAMBA

Reputation: 725

AWS Lambda only invoking the first promise function

I am trying to bulk insert data into sql server using lambda, the code only inserts the data for the first argument provided for the promise.all , while trying to run the code offline using serverless, everything works fine.

module.exports = async (context, event, callback) => {
    let bulkInsert = async (table, db) => {
        return new Promise(async function (resolve, reject) {
            const request = null;
            try {
                console.log("Bulk inserting data")
                const request = await db.request();
                try {
                    var result = await request.bulk(table);
                    console.log(result)
                    resolve(result)
                } catch (err) {
                    console.log(err);
                    reject(err)
                }
            } catch (err) {
                console.log("Error Occured while inserting data.")
                console.log(err)
                reject(err)
            }
        });
    };
    //Read file from S3
    var file = s3.getObject(params).createReadStream();
    var buffers = [];

    try {

        //Get the metadata for the object
        let s3Header = await s3.headObject(params)
            .promise()


        let db;
        let insertedTaskID;
        try {
            db = await new sql.ConnectionPool(config).connect();
        } catch (err) {
            console.error("Connection failed: " + err);
            throw err;
        }


        file.on("data", function (data) {
            buffers.push(data);
        });

        file.on("end", async function () {
            var buffer = Buffer.concat(buffers);
            var workbook = xlsx.parse(buffer);
            console.log("No of sheets in workbook are:", workbook.length);


            console.log("Remaining Execution Time ", context.getRemainingTimeInMillis())

                console.log("Validation Completed ")
                let firstTableData = getData("10002", workbook, "0")
                let secondTableData = getData("10002", workbook, "1")
                let thirdTableData = getData("10002", workbook, "2")
                let fourthTableData = getData("10002", workbook, "3")

                console.log("Inserting rows to DB")
                //Bulk insert the data into respective tables
                try {
                    await Promise.all([
                        bulkInsert(firstTableData, db),
                        bulkInsert(secondTableData, db),
                        bulkInsert(thirdTableData, db),
                        bulkInsert(fourthTableData, db)

                    ]).catch(err => {
                        console.log("Error on Bulk Insertion ")
                        console.log(err)
                    })


                    console.log("Completed Insertion")
                } catch (err) {
                    console.log("Bulk Insert Failed")
                    console.log(err)
                }

            }
        });

        callback(null, "OK");

    } catch (err) {
        console.log(err)
        callback(err);
    }
};

Here is the lambda logs, the request is ending before inserting to other tables.

    08:26:42
    2019-07-06T08:26:42.266Z    da7e5fd0-acf9-48f0-8dfc-5a2ac712f035    INFO    Bulk inserting data

    08:26:42
    2019-07-06T08:26:42.266Z    da7e5fd0-acf9-48f0-8dfc-5a2ac712f035    INFO    Bulk inserting data

    08:26:42
    2019-07-06T08:26:42.287Z    da7e5fd0-acf9-48f0-8dfc-5a2ac712f035    INFO    Bulk inserting data

    08:26:42
    2019-07-06T08:26:42.287Z    da7e5fd0-acf9-48f0-8dfc-5a2ac712f035    INFO    Bulk inserting data

    08:26:42
    2019-07-06T08:26:42.387Z    da7e5fd0-acf9-48f0-8dfc-5a2ac712f035    INFO    { rowsAffected: 3 }
    
    08:26:42
    END RequestId: da7e5fd0-acf9-48f0-8dfc-5a2ac712f035

Upvotes: 0

Views: 149

Answers (1)

James
James

Reputation: 82096

The lambda would appear to be exiting before the rest of the bulk inserts have had a chance to finish, you should move your callback call into the end event to make sure you only exit the lambda after all the bulk calls have run e.g.

file.on('end', async () => {
  ...
  callback(null, 'OK');
});

Also, FWIW if your Lambda is async then you shouldn't need to wrap await calls in that context with try/catch blocks, let them throw and the Lambda will handle them for you.

Upvotes: 2

Related Questions