Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Azure Functions and Lazy Initialization With Couchbase Server

DZone's Guide to

Azure Functions and Lazy Initialization With Couchbase Server

Initializing a Couchbase Cluster object is an expensive operation. Luckily — contrary to what you may assume — there is a way to save state between Azure Function calls.

· Database Zone
Free Resource

Traditional relational databases weren’t designed for today’s customers. Learn about the world’s first NoSQL Engagement Database purpose-built for the new era of customer experience.

Azure Functions are still new to me, and I’m learning as I’m going. I blogged about my foray into Azure Functions with Couchbase over a month ago. Right after I posted that, I got some helpful feedback about the way I was instantiating a Couchbase cluster (and bucket).

I had (wrongly) assumed that there was no way to save state between Azure Function calls. This is why I created a GetCluster() method that was called each time the function ran. But, initializing a Couchbase Cluster object is an expensive operation. The less often you instantiate it, the better.

You can follow along with the updated source code for this blog post on GitHub.

Static State

I had a hard time finding documentation on whether I could use a static object for reuse between function calls. I suppose I should have experimented, like fellow Microsoft MVP Mark Heath did. Instead, I posted the question to StackOverflow.

In short... yes. A Cluster, instantiated and saved to a static member, can be reusable between function calls. According to Mark’s post above, there’s no guarantee how long this value will survive. But that’s an expected trade-off that you make when going “serverless.”

Lazy Initializing Within Azure Functions

Simply using a static member would work, but it’s not thread-safe. There are a few ways to tackle that issue, but an easy way that’s built right into the .NET framework is to use Lazy Initialization with Lazy<T>.

Lazy Initialization in Azure Functions

First, I removed the GetBucket and GetCluster methods. Next, I created a Lazy<IBucket> property to replace them.

private static readonly Lazy<IBucket> Bucket = new Lazy<IBucket>(() =>
{
    var uri = ConfigurationManager.AppSettings["couchbaseUri"];
    var bucketName = ConfigurationManager.AppSettings["couchbaseBucketName"];
    var bucketPassword = ConfigurationManager.AppSettings["couchbaseBucketPassword"];
    var cluster = new Cluster(new ClientConfiguration
    {
        Servers = new List<Uri> { new Uri(uri) }
    });
    return cluster.OpenBucket(bucketName, bucketPassword);
});

I just made a single property for a bucket, since that’s all I need for this example. But if you need to use the cluster, you can easily make that its own Lazy property. (Once you have a cluster, getting a bucket is a relatively cheap operation.)

Using a Lazy Property

When you instantiate a Lazy<T> object, you supply it with an initialization lambda. That lambda won’t execute until the Value property is actually called for the first time.

var lazyObject = new Lazy<string>(() =>
{
    // this code won't be called until 'lazyObject.Value' is referenced
    // for the first time
    return "I'm lazy!";
});

For instance, notice the Value between Bucket and GetAsync in the updated version of my Azure Functions:

var doc = await Bucket.Value.GetAsync<MyDocument>(id);

If that’s the first time Value is used, the cluster will be initialized. Otherwise, it will use the already initialized cluster (try experimenting with a Guid instead of a Bucket).

Summary

State can be saved between Azure Function calls by using a static member. Make sure that it’s thread-safe (by using Lazy<T> or something like it). Don’t make any assumptions about how long that object will be around.

Learn how the world’s first NoSQL Engagement Database delivers unparalleled performance at any scale for customer experience innovation that never ends.

Topics:
database ,azure ,couchbase server ,tutorial ,lazy initialization

Published at DZone with permission of Matthew Groves, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}