An attempt to go some serverless: Azure Functions

Tarik Kilic
Beerwulf
Published in
6 min readDec 10, 2018

--

It was shorter than a year ago that in Amsterdam, I joined Microsoft Tech Summit to get a better feeling on what’s the latest on Microsoft developer community and Azure. Once in a while, it’s nice to take a look at the broader overview instead of focusing on your given technology stack, which usually kick-started by someone else. From many cool presentations, demos and short brainstorm sessions with Azure engineers from Redmond, one thing I was impressed most and wanted to get a deeper dive on: concept of serverless computing, Azure Functions to begin with. I’m not going to tell you what is the concept of serverless computing. I’m pretty sure there are articles that nailed it better than I would. I will focus on questions of what, when, how in a more focused scope to Azure Functions.

What?

Azure Functions is a serverless computing service that enables you to create code parts that is running on different kind of invocations (on-demand API, triggered by other services, timer based) without giving any care to managing infrastructure of application. It is an obvious end product of evolution on cloud infrastructure in last years that is basically aiming to make managing infrastructure of your software easier. It is safe to say that while developing an Azure Function app, you develop and deploy. Scaling your app? Not your problem. Managing your server? Not your problem. Rest is just monitoring your software if you like(I hope you do).

When?

Then there comes THE question: when to use Azure Functions? It’s nothing but statement of an obvious fact to say that latest technology stack is not necessarily best solution for your application. You need to find really good engineering reasons to change your “I know this better than my name” technology stack to something new and shiny. Otherwise, you’ll end up monitoring something you barely have production experience. This is the case if you’re lucky and smart enough to think about monitoring. If not, you’ll be just trying fixes and crossing your fingers that it’s going to work.

In our experience, we spent some time on thinking and researching if we’re really going to benefit from Azure functions for given functionality. That was an isolated batch-processed data serving solution for 3rd parties we’re working with. The keyword for us was “isolated”. Given the fact that we had backup solution to fallback and that was not a critical customer facing functionality which would be chaotic to face fallback hustle, we decided it was a good area where we could get some experience on a new technology while safely delivering an optimized functionality.

What makes Azure functions on our engineering teams point of view great is places where you can avoid problem of cold start while being able to isolate deployment from rest of application and of course enjoying great scalability advantages. In our case, we saw a dramatic decrease in response times with new approach, which was not suffering from cold-start and was scaling smoothly. To get a deeper understanding on cold start you can check article below from Azure Functions team blog.

How?

Here comes the fun part, at least for me. Finally you’ll get to see some code. This part will contain some code snippets for basic examples implemented on Azure functions including usage of Azure Cosmos DB read-write operations. Let’s start with really basic examples. In whole article we’ll be using C# to code Azure Functions but there are also other available languages.

Event Triggers:

There are 5 event triggers that you can use in Azure Functions; HTTP, Timer, Azure Cosmos DB, Blob, Queue. I’ll give examples for the first two. HTTP functions are triggered by HTTP request recieved by defined endpoint, if applicable with defined arguments. Timer triggered functions run whenever the CRON expression that defined in code is valid.

Create an Azure function in Visual Studio:

It’s pretty easy to create an Azure function in Visual Studio. You need to have Azure development tools installed with Visual Studio. If you have it, after 2 simple steps, you have your snippet created for developing an Azure Function. You also have an option to create it from Azure Portal which will not be covered in here.

Create an Azure Function from Visual Studio

You can select between two versions of Azure Functions; v1(.NET Framework) and v2(.NET Standart).

HTTP Trigger:

HTTP trigger allows you to have a standart webhook+API endpoint where code runs whenever defined HTTP requests are recieved. You define requirements for desired HTTP request in HttpRequestMessage object on parameters which is decorated by HttpTrigger attribute (such as authorization levels, allowed Http methods, route). You can have 5 authorization levels defined in AuthorizationLevel enum; Anonymous, Admin, Function, System and User. In Admin, Function, System levels it requires keys that are equivalent to level of corresponding authotization mode. For User, it allows access to requests that include a valid authentication token.

Timer trigger:

Timer trigger allows you to run code based on a specified schedule. TimerInfo object is decorated by TimerTrigger attribute, which is accepting a CRON expression defines in which schedule your function will run.

Timeout on Functions:

In consumption plan, functions have a default 5 minutes timeout to have complete each execution. If you need more than 5 minutes for any given execution, you need to decorate your function with Timeout attribute. I didn’t check what’s the maximum timeout you can define but in a few places I defined it as 30 minutes and it worked fine. You can see example in the code snippet above.

Azure Cosmos DB integration:

Azure Cosmos DB is a multi-model database service that supports several database technologies, mainly used for its advantages on storing unstructured data. I’m not going to cover what is Cosmos DB since it deserves its own blog post in detail, but will explain how to integrate it with Azure functions for several scenarios.

Great benefit of integrating Azure Cosmos DB to your function is easy bindings to configure. For instance in the example below, timer trigger is reading bulk data from a source for each time, and inserting multiple records to Cosmos DB via IAsyncCollector, which is decorated by DocumentDB attribute for connection settings. It is one of the easiest configurations for database operations.

In the next example, we have an HTTP endpoint querying Cosmos DB from SQL query that takes path arguments directly and binding results to a parameter of function.

For the next example, first I want to raise a question: Given the fact that serverless approach can suffer from cold start, how can we avoid cold start on functions that has database connections established? Or in general, I/O operations that establishing a client first. This is a fair concern for systems that designed for production purposes. Luckily, there is an answer for that. Let’s dive into that.

Functions has a lifecycle. Depending activity, Azure Functions create a VM and manage the lifecycle based on app service plan. That at least for a given time it keeps function runtime live between consequent requests. Our goal is to use some resources/clients between many requests to reduce establishment or calculation overhead each time. For our particular case, Azure Cosmos DB client, it’s wise to keep a client which operates between database and function live for many requests. You can use DocumentClient as a singleton for that purpose. In next code snippet, DocumentClient is established as a singleton. Azure Function runtime treats static properties of function class as a singleton and keep them live during runtime lifecycle.

There are more optimizations can be applied to DocumentClient based on Azure Cosmos DB performance tips and capabilities of Azure Function runtime but that looks like the topic of a seperate blog post to me. I will try to keep posting to this thread as much as possible.

--

--

Tarik Kilic
Beerwulf

building teams, products and systems that scale. currently @SurveyMonkey, previously @Beerwulf.com