Recurring Activities Using Durable Functions

Eternal Orchestrators in Durable Functions on Azure

Igor Izotov
Jan 16 · 5 min read

TL;DR. I continue this mini-series on scheduling recurring serverless activities using Azure Functions. In my previous post I explored timer-triggered Functions, in this little write-up I talk about setting up a recurring job using Eternal Orchestrators in Durable Functions on Azure, highlighting some scheduling nuances along the way.

Durable Functions is a framework on top of Azure Functions that lets you design stateful serverless functions. The framework manages execution state, checkpointing and restarts transparently. At the time of writing, C#, JavaScript and F# are supported. The three components of a Durable Function are: Orchestrator, Starter Function and an actual Activity. The Starer Function kicks off the Orchestrator, the Orchestrator manages state and executes your Activities. Simple, huh?

An Orchestrator can execute a finite workflow or can run indefinitely, which is useful for setting up recurring activities. This flavour of the Orchestrator is (very aptly) called Eternal Orchestrator.

Right, let’s explore this concept and some of its nuances using an example. In this example I will be using the in-portal experience but you’re welcome to use VS Code.

Create a New Azure Function

Create a new JavaScript Azure Function — consumption plan is perfectly fine:

For the following couple of steps, fire up the App Service Editor using this URI: https://{function-name}, replacing {function-name} with the name of your Azure Function

Using the App Service Editor, add package.json to /wwwroot with the following content:

Using the built-in console in the App Service Editor (CMD+Shift+C) or via Kudu run npm install from /wwwroot to install the packages:

Create a Starter Function

Every Durable Function needs a starter Function that can be triggered using any of the supported triggers; in this case we will create a universal HTTP-based starter, calling it starter. You will be asked to install the Durable Functions extension:

Use the following code:

Create a New Activity

We now need to have something to orchestrate — a Durable Function Activity we’ll call doImportantStuff. Use the following code to simulate a task that takes about 5 seconds to run:

Side Note: Recurrence Patterns

Before we create an orchestrator, let’s talk a bit about a few ways to set up a recurring schedule. In the examples below I use 10 seconds as an arbitrary value:

  • Option 1. Run doImportantStuff every 10 seconds or immediately if the previous invocation ran for longer than 10 seconds. This will ensure non-overlapping executions whilst governing the minimum frequency of executions — once every 10 seconds at least.
  • Option 2. Run doImportantStuff, then wait for approx 10 seconds and repeat. This is similar to Option 1 in that it ensures non-overlapping executions, but this pattern ensures a consistent pause between invocations:
  • Option 3. Run doImportantStuff repeatedly back-to-back without overlaps. This can be wasteful, since it may result in an overly frequent execution of your activity, especially if it’s a short-running one. The good thing is that the Durable Functions Framework will ensure non-overlapping executions. Also, consider tweaking the host.json settings pertaining to Durable Functions and keep in mind the overall work thresholds of the Azure Functions Runtime:
  • Option 4. RundoImportantStuff approximately every 10 seconds regardless if its previous invocations are still running. This is a variation of the Timeout Pattern and will result in possible overlaps and race conditions, so make sure to deal with these situations in your activity’s code or avoid this recurrence pattern altogether:

Strictly speaking, none of these options define a calendar-based schedule, instead they are all interval-based, which is a useful approach to have in your inventory. For a calendar-based schedule you can use timer-based Functions or cron jobs — please refer to my other post talking specifically about that.

Right, time to create an Orchestrator:

Create an Eternal Orchestrator

A Durable Function Orchestrator is the brains of the operation, create a new one calling it eternalOrchestrator that will keep scheduling itself in perpetuity in a managed and controlled manner. The code includes each of the four aforementioned recurrence patterns, note the subtle differences in every option:

Starting the Orchestrator

We need to grab our starter function’s URI and replace {functionName} with the name of the orchestrator we would like to kick off, eternalOrchestrator in our case:

Issue a GET request using the copied URI using curl or Postman to get the eternal orchestrator running (if you’re using curl, pipe the json output to jq to pretty-print it).

If you use your browser, you may see two GET requests issued due to a favicon.ico request, which will result in two orchestration loops being kicked off. To prevent this you can implement the singleton pattern in your orchestrator

Notice the URIs in the json output that are handy for monitoring and terminating your orchestrator:

Look at the Azure Function logs and notice how the doImportantStuff activity and the eternalOrchestrator orchestrator spring to life:

That’s all folks, thanks for reading and until next time!

Igor Izotov

Written by

Cloud Solution Architect @ Microsoft Australia. Opinions shared are my own.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade