Reputation: 1569
I am using Azure function : Timer Trigger and Cosmos DB feed trigger.
Timer Trigger Function
I have Output binding of Cosmos DB in Timer Trigger function. I am creating connection with Service Bus client and reading messages in batch and uploading in Cosmos DB as shown below. My question is for every runtime Cosmos DB connection will be created? if yes, how i can share the connection? How can i improve SB connection as well so every runtime it will not create new connection. Am I doing it right way in terms of performance?
Cosmos DB feed trigger
In this function I have Cosmos DB as an trigger and outbound with SB. For every request new connection will be created or function will reuse existing object for both Cosmos and SB connection?
Upvotes: 0
Views: 831
Reputation: 26057
Another alternative would be to have a Service Bus trigger and add a document as a message arrives instead of executing a timer and handling a batch. This approach includes the following benefits:
Upvotes: 1
Reputation: 4870
AFAIK, there are three recommended ways to share expensive data between functions on a server to improve performance:
Use static client variables: Static variables are reused for every function invocation, instead of creating a new one, this saves memory and gives performance benefits. When the load is less, only one server instance is created for functions in background, so static variables are reused for multiple functions invocations within the same server instance. But if more than one servers are created, every server instance will have its own static variable, which will be reused by function invocations handled within the same server instance. This is still much better than creating a new connection for every invocation.
Check out this detailed blog for performance load testing proofs of this as well.
Use MemoryCache: This would allow you to share a cache between functions. For example:
static MemoryCache memoryCache = MemoryCache.Default;
public static async Task<object> Run(HttpRequestMessage req, TraceWriter log)
{
var cacheObject = memoryCache["cachedCount"];
var cachedCount = (cacheObject == null) ? 0 : (int)cacheObject;
memoryCache.Set("cachedCount", ++cachedCount, DateTimeOffset.Now.AddMinutes(5));
log.Info($"Webhook triggered memory count {cachedCount}");
return ...
}
Here the code is trying to find the count in the cache, increment it, and save it with a five minute expiry. If we copy this same code to two functions within the same Azure Function App, then sure enough they each can see the count set by the other one. Note that, this cache will lose its contents every time you edit your code.
Check out this blog for more details around this.
Use Dependency Injection: Use DI to create Singleton instances and use them. Check out Use dependency injection in .NET Azure Functions. ServiceBusClient can be registered for dependency injection with the ServiceBusClientBuilderExtensions.
Note: The disposing of the static clients will be automatically done by .NET core runtime, if they implement IDisposable interface. Don't manually dispose it, otherwise it wont be reused. Further, ensure that the static clients are thread safe. As the MS Doc says:
Establishing a connection is an expensive operation that you can avoid by reusing the same factory and client objects for multiple operations. You can safely use these client objects for concurrent asynchronous operations and from multiple threads.
It is safe to instantiate once and share ServiceBusClient
.
Additional links:
Let me know if you have any follow-up questions.
Upvotes: 3