Skip to content

Connection Hang Intermittently in AWS Lambda #1734

Open
@shubsaini09

Description

@shubsaini09

I am using AWS Lambda with provisioned concurrency. I am creating pool as part of Lambda initialization. As part of this process, I create a pool with min 1 and max 100. Whenever the request comes I use getConnection() to get the connection and then execute() to run our insert query. Sometimes I see that code fails at the line where we do getConnection() without any error. Our lambda is attached to the APIG, as per the APIG logs, I see that lambda returned null. I have added detailed logging in our Lambda but no trace of any error. The console statement before getConnection() gets printed but not after, not even in catch block.

One of the pattern that I noticed is that this happens only when there is no request for sometime and then request comes. The first request fails but all subsequent requests are successful. I understand that connection might be stale and may not be available but I have a custom retry logic in place which would retry if the error comes but there is not error thrown to retry.

// index.mjs

import { createDBConnection } from './dbConnection.js';
import { insertData } from './insertData.js';

const poolConfig = {
	user,
	password,
	connectString,
	poolMax,
	poolMin,
	poolIncrement,
	transportConnectTimeout,
	poolAlias,
	enableStatistics: true
};
await createDBConnection(1, poolConfig, 'aliasName' );

export const handler = async (event) => {
    const dbResponse = await insertData(event.body);
    return { statusCode: 200, body: JSON.stringify(dbResponse) };
}
// insertData.js

const insertVoiceBotdata = async (payload) => {
	const binds = getQueryAndData(payload); // gets the query and create the formatted binds
	const dbResponse = await executeQuery(QUERY, binds, 'aliasName', true);
	return {
		status: dbResponse.rowsAffected ? dbResponse.rowsAffected > 0 : false,
		status_description: dbResponse.message,
	};
};
// dbConnection.js

const oracledb = require('oracledb');

oracledb.outFormat = oracledb.OUT_FORMAT_OBJECT;

async function createDBConnection(retryAttempt, poolConfig, poolAlias) {
	try {
		oracledb.getPool(poolAlias);
		return true;
	} catch (error) {
		try {
			await oracledb.createPool(poolConfig);
		} catch (connectionError) {
			console.error('Error creating pool: ', connectionError);
			if (retryAttempt > Number(retries)) {
				throw connectionError;
			}
			const delayInMilliseconds = Number(baseDelayInMilliseconds) * 2 ** retryAttempt;
			await new Promise((resolve) => { setTimeout(resolve, delayInMilliseconds); });
			const nextRetryAttempt = retryAttempt + 1;
			return createDBConnection(nextRetryAttempt, poolConfig, poolAlias);
		}
	}
}

const executeQuery = async (query, binds, poolAlias, autoCommit = false) => {
	let connection;
	try {
                console.log('getting connection...'); // printing
		connection = await oracledb.getConnection(poolAlias);
		console.log('received connection...'); // not printing
		const queryResponse = await connection.execute(query, binds, { autoCommit });
		console.log('queryResponse...', queryResponse);
		return queryResponse;
	} catch (error) {
		console.error('Error executing query:', error);
		return error;
	} finally {
		try {
			if (connection) await connection.close();
		} catch (closeError) {
			console.error('Error closing connection:', closeError);
		}
	}
};

module.exports = {
	executeQuery,
	createDBConnection,
};

Any help is appreciated. Thanks

Oracledb version - 6.7.0
platform.arch - x86_64
process.platform - linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions