0

I cannot find clear information on how to manage database connections (MongoDB in my case) from an Azure function written in Javascript.

The Microsoft document below says to not create a connection for each invocation of the function by using static variables in C# using .NET Framework Data Provider for SQL Server and the pooling is handled by the client connection. It does not describe how to do this in Javascript.

https://learn.microsoft.com/en-us/azure/azure-functions/manage-connections

A solution of creating a global variable to hold the database client between invocations is described here but the author is not confident this is the correct way to do it.

http://thecodebarbarian.com/getting-started-with-azure-functions-and-mongodb.html

Has anyone used this in production or understand if this is the correct approach?

1

1 Answer 1

7

Yes, there's a very close equivalence between C#/SQL storing a single SqlConnection instance in a static variable and JS/MongoDB storing a single Db instance in a global variable. The basic pattern for JS/MongoDB in Azure Functions is (assuming you're up to date for async/await - alternatively you can use callbacks as per your linked article):

// getDb.js

let dbInstance;

module.exports = async function() {
    if (!dbInstance) {
        dbInstance = await MongoClient.connect(uri);
    }
    return dbInstance;
};

// function.js

const getDb = require('./getDb.js');

module.exports = async function(context, trigger) {
    let db = await getDb();
    // ... do stuff with db ..
};

This will mean you only instantiate one Db object per host instance. Note this isn't one per Function App - if you're using a dedicated App Service Plan then there will be the number of instances you've specified in the plan, and if you're using a Consumption Plan then it'll vary depending on how busy your app is.

Sign up to request clarification or add additional context in comments.

6 Comments

This answer is a life-saver. I didn't know that global variables are passed around the entire host instance and I thought the connection dies along with any variables after an execution is done. Since it's supposed to be a stateless function
My question for you @MarkXA is - what would be the maximum concurrent functions utilizing this single connection simultaneously before something breaks?
The client itself shouldn't actually break - it'll just wait if the connection pool is full. More generally it'll depend on your actual database. If it's fixed scale then yes it can become a bottleneck if Azure Functions gets too busy. If it's set to autoscale (e.g. Cosmos DB using the MongoDB API) then that should be less of a problem.
Oh ok. Thank you for that clarification. Much appreciated
Isn't this code containing a race condition? What would a safer code looks like?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.