AWS Lambda functions NodeJs for postgreSQL - timeout error
Asked Answered
C

3

7

I am new to AWS. I am trying to connect to AWS RDS postgreSQL instance using Lambda functions. I followed the aws documentation. But it uses python for Lambda functions. Below is my code.

'use strict';
var pg = require('pg');
exports.handler = function (event, context) {
    var dbConfig = {
        username: '<username>',
        password: '<password>',
        database: '<database>',
        host: '<db-endpoint>',
    };
    var client = new pg.Client(dbConfig);
    try {
        client.connect();
        context.callbackWaitsForEmptyEventLoop = false;
        client.end();
    }
    catch (err) {
        console.log(err);
        client.end();
    }
};

I am getting timeout error as below

START RequestId: 368e619e-ed9d-4241-93a5-764ee01aa847 Version: $LATEST
2020-06-15T16:28:18.911Z    368e619e-ed9d-4241-93a5-764ee01aa847    INFO    connected
END RequestId: 368e619e-ed9d-4241-93a5-764ee01aa847
REPORT RequestId: 368e619e-ed9d-4241-93a5-764ee01aa847  Duration: 20020.16 ms   Billed Duration: 20000 ms   Memory Size: 128 MB Max Memory Used: 70 MB  Init Duration: 150.01 ms    
2020-06-15T16:28:38.901Z 368e619e-ed9d-4241-93a5-764ee01aa847 Task timed out after 20.02 seconds

Please advise on the error.

I have few other questions to ensure if my code is correct

  • I gave db instance endpoint url for db-endpoint. is that right? or if not what should i use there?

  • is there any proper documentation available, for the beginners like me, about Lambda functions with nodejs to connect postgres on RDS?

Cameleer answered 15/6, 2020 at 16:45 Comment(0)
B
5

You're not returning anything from the lambda. So the request keeps hanging without a response until it times out.

Use the third argument callback supplied to the handler to respond or return a Promise.

'use strict';
var pg = require('pg');
exports.handler = function (event, context,callback) {
    var dbConfig = {
        username: '<username>',
        password: '<password>',
        database: '<database>',
        host: '<db-endpoint>',
    };
    var client = new pg.Client(dbConfig);
    try {
        client.connect();
        context.callbackWaitsForEmptyEventLoop = false;
        client.end();

        //send the response
        callback(null,"Some Response")
    }
    catch (err) {
        console.log(err);
        client.end();
        callback(err)
    }
};

AWS example : AWS Lambda NodeJS Connect to RDS Postgres Database

You can read the official js docs with all methods and properties here : https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/RDS.html

Hope this helps !

Bratislava answered 15/6, 2020 at 16:58 Comment(4)
Thanks for your reply. It works. But I have a question. In the other stack overflow question which you shared, Pool function is used to initialise. But in my code, I used Client function. Whats the difference?Cameleer
Its called connection pooling. ashnik.com/…Bratislava
Thanks. AWS documentation doesn't help at all. Especially for a beginner like me. Is there any other tutorial or documentation available that explains in simple terms about the lambda function using node.js for RDS postgres?Cameleer
@HemantParashar why does pooling requires in lambda?Dublin
B
3

Here is the answer for async/await syntax

const { Client } = require("pg");

exports.handler = async (event, context, callback) => {
  const dbConfig = {
    host: process.env.RDS_HOSTNAME,
    user: process.env.RDS_USERNAME,
    password: process.env.RDS_PASSWORD,
    port: process.env.RDS_PORT,
    database: process.env.RDS_DATABASE,
  };
  const client = new Client(dbConfig);

  try {
    await client.connect();
    const res = await client.query("SELECT * FROM your_table");
    await client.end();
    callback(null, res.rows);
  } catch (err) {
    await client.end();
    callback(err)
  }
};

Bootblack answered 22/6, 2022 at 9:21 Comment(0)
F
0

I'm not sure if you're still having issues but my issue was using the callback parameter.

If you start a new Serverless framework project they no longer wrap responses with callback anymore. They just return. Try giving that a go. I'm not sure the inner workings of why using callback would cause issues, but once I removed it my calls no longer hung or caused a "pool has ended" errors.

I also recommend using this package for Serverless projects.

Lastly, in your try/catch add finally to end your session:

//client.clean() is from the library I linked, not pg-node
//though if you use pg-node, you could do pgPool.end() in the finally instead

finally {
  await client.clean()
}

This way it always runs at the end of your lambda and you have to put it only in one spot.

Frangipani answered 9/4, 2023 at 13:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.