cancel
Showing results for 
Search instead for 
Did you mean: 

Connecting to Neo4j AuraDB from AWS nodejs lambda

feliciav
Node

Does anyone have difficulty connecting to the Neo4j AuraDB from AWS nodejs Lambda?
My code connects to the Neo4j AuraDB and all test cases runs locally.
The same code do not appear to connect to the Neo4j AuraDB when it is deployed in AWS Lambda.
The lambda is running as a 'public' lambda (i.e. not in a VPC) and it definitely have internet access.

I have set up the driver to show logging at the debug level.
In the local test cases, I can see debug statements showing Connection established.
But in the lambda logs, none of these debug statements are showing.
It just doesn't seem to be able to connect to Neo4j AuraDB.

3 REPLIES 3

david_allen
Neo4j
Neo4j

Please post your lambda code and what logs you do have; it's possible this is a lambda deploy error, or something else. What happens when you hit the lambda you've deployed?

feliciav
Node

Thanks David for following up.
I did further debugging with a very simple lambda to establish connectivity to Neo4j. That works. So I think there may have been too many promise chaining happening. I think I know where my mistakes are.

Now facing another problem with how AWS lambda works.
In order to share the connection across multiple promises, the driver is initialised once and re-used.
Each promise is responsible for closing the session.
At the end of the lambda execution, the lambda function is responsible for closing the driver connection.
All good and works fine.

The problem becomes when the lambda is called in quick succession (as can happen). AWS Lambda will use a 'hot' container for the previous exited lambda call and use the driver that was previously initialised and then closed. I get errors then. If I leave it a bit and re-trigger the lambda, it works fine.

I think I have just set driver initialisation wrong. Or I have to figure out how to verify connection on initialisation and then force it to re-connect.

Sample code for setting up the driver

const NEO4J = require('neo4j-driver');
const neo4jURI = 'neo4j+s://xxxxxxxxx';
const neo4jUser = 'xxxxx';
const neo4jPassword = 'xxxxxx';

// Export a module-scoped Neo4j Driver to be shared across functions.
const neo4jDriver = NEO4J.driver(neo4jURI, NEO4J.auth.basic(neo4jUser, neo4jPassword), {logging: {
level: 'debug', logger: (level: string, message: string) => console.log(level + ' ' + message)
}});

module.exports = neo4jDriver;

Code snippet for using the neo4jDriver

const neo4jDriver = require('../../services/neo4j.client');
const session = neo4jDriver.session();

// cypher is whatever the cypher statement to be ran
// cypherParam is whatever parameters to be associated with
const writeTxPromise = session.writeTransaction((tx:any) => tx.run(cypher,cypherParams));

  writeTxPromise
    .then((result: any) => {
      session.close();
      resolve(result);
    })
    .catch((e: any) => {
      session.close();
      reject(e);
    });

The lambda may be running through multiple promises that has the above snippets.
At the end of those promises, the lambda issues this statement:

Promises....
.then( .... )
.catch( ...)
.finally(() => {
// Close the neo4jDriver as all transactions have completed.
neo4jDriver.close();
});

Any ideas of how to verify connection? Error only occurs when the lambda is called in quick succession.

We initialise the driver at container startup (outside the actual lambda function) and then the function is responsible for creating and closing sessions. This way concurrent lamdba executions share the driver but create and destroy their own sessions.

The driver is destroyed when the container is shut down - we haven't worked out how to gracefully close the driver as the container is shutdown, but we haven't experienced any problems with not doing that.