Description
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