-->

03/05/2021

Azure Durable Functions - Starter, Orchestrator and Activity Fucntions

Use Case: A user starts to book a trip, which consists booking a Flight and Hotel and then pay for complete trip. 

Back in the day, the answer used to be a single server-side application which is complex enough to take care of everything. Now we call it Monolith application. 

Now we use microservices architecture to seperate the concerns at domain level. With Function as a Service, it even evolved to a Serverless state, where you can provision the services even without using any infrastructure.

Azure Functions is one of the critical components of serverless designs, and here is what we know about them:

Even-Driven: Azure functions are invoked based on a trigger caused by events like making a http call (or) adding a message to a Queue (or) adding a object to a blob storage (or) adding a new record to CosmosDB and many others.

Short-Lived: Azure functions are meant to for short period of excutions and to address a simple tasks which makes it more suitable for Microservices part of the design. Keep it simple and seperated.

Stateless: Azure Functions doesnt save any state infirmation of objects, thus the trigger mechanism will have both inputs and outputs. 

Now considering above facts, i have created a design for above Use Case.

Now the deisgn is pretty much simple and self-explanatory. But here is the catch.

Inorder to confrim booking to the user, both flight and hotel bokings need to be done to finalize the cost of the trip. This means "Confirm Booking" should execute only when both "Book Flight" and "Book Hotel" are sucessful. 

Give a thought for a minute how you going to handle in your opinion.

Here are the problems: 
1. Both "Book Flights" and "Book Hotel" functions might not be executed at the same millisecond. YOu are not sure which one will finish first.
2. One of the functions might not be avilable right away. Due to the fact Azure function instances were created for every 10 seconds based on demand.
3. What if one of the function gave an error.
4. How do you orchestrate the out put of two functions withholding data until both of them were finiched exceuting. Remeber Fucntions are stateless. 

Durable Fucntions: Durable Functions is a library that brings workflow orchestration abstractions to Azure Functions. It introduces a number of idioms and tools to define stateful, potentially long-running operations, and manages a lot of mechanics of reliable communication and state management behind the scenes.

Says Microsoft, but let us implement one and show you what it means.

Step 1: Create a Azure Function App.


Durable Function is a open source package embraced by micrisoft azure. For this we need to install the package. For that we need to create "package.json" file. This file will hold information of all the packages installed.

Open the Function App and in left hand menu click on "Console" in "Development Tools" category.   
Run below command.


This will create a new file "package.json". Now click on "App Files" in "Fucntions" category. Open the package.json file and add below code.
{
"name": "DuraFuctionDemo",
"version": "1.0.0"
}
Save the chnages and go to overview and restart the Function App.

Step 2:  Install required packages.
Open Console again and run "npm install durable-functions". This might generate a new file with name "package-lock.json".  Go to "App files" again and copy the content of "package-lock.json" file and paste it to "package.json" file and save.
Go to Overview and restart the Fucntion App again.

Step 3: Create Fucntions.
Durable functions has 3 roles.

1. Starter Fucntion - Invocation to this function will be handed over to Orchestartor Function.
2. Orchestartor Function - This function will make calls to Activity Fucntions based on context.
3. Activity Function - This function will do actual excution of the task and send back the response back to Orchestartor Fucntion.

Create a function, select "Durable Functions HTTP starter" as the template.

Leave the code as is.

Create 1st Activity Function.

Paste below code in BookFlight function.
module.exports = async function (context) {
return `Flight Bookings for the trip have been - ${context.bindings.name}!`;
};
Create 2nd Activity Function.

Paste below code in BookHotel function.
module.exports = async function (context) {
return `Hotel Bookings for the trip have been - ${context.bindings.name}!`;
};
Create Orchestrator function.

Paste below code in "BookingOrchestrator" function.
const df = require("durable-functions");

module.exports = df.orchestrator(function* (context) {
const outputs = [];

// Asyncronously calls both activity functions.
outputs.push(yield context.df.callActivity("BookFlight", "Confirmed"));
outputs.push(yield context.df.callActivity("BookHotel", "Confirmed"));
return outputs;
});
We all all set for execution.

Step 4: Test the functionality.
Open Starter Function, click on "Test/Run" and give the orchestrator function name as parameter.

or you can copy the function url from "Get Function URL" from overview and replce below highlighted function name with orchestrator name.

https://durafunctiondemo.azurewebsites.net/api/orchestrators/{functionName}?code=oPaGqBv7jRVOxQjuJkiEtA/caBxb6Py4IzHCW0iE/okQXfDEi1k9kw==

This is the response and the "statusQueryGetUri" will give the final response combining the responses of all activity functions.

Here is the final response from Orchestrator function.

Step 5: What if one of the activity functions is not avilable.
Lets Disable "BookHotel" activity function.

Now repeat the Step 4  but browsing the url https://durafunctiondemo.azurewebsites.net/api/orchestrators/{functionName}?code=oPaGqBv7jRVOxQjuJkiEtA/caBxb6Py4IzHCW0iE/okQXfDEi1k9kw==

and then browse the url from "statusQueryGetUri".

You can see that the Orchestrator function ran the "BookFlight" function, but due to the fact "BookHotel" function is unavilable, its holding its state waiting for the response from "BookHotel" function.

Question is where is the state information saved for time being.
Ans: Its in a Azure Queue with all related information. Let me show you.


Now, lets enable the "BookHotel" activity fucntion. and then the orchestrator function will pick where it left and process the final output.
Once you enabled the Activity function, the Message saved in Azure Queue by Durable function is cleared as the Orchestrator function will process the final output.

Finally lets talk about Billing.
Unlike Azure functions, Durable-Functions were billed based on number of calls+ time of execution.
But, Orchestrator function has a special feature "Stop-Resume" behavior. Once one of the fucntion yeild the result, instead of waiting (synchronously), Orchestrator function will stop and saves its state as a message in a Queue. Once the response from second function arrives, it will start again and finishes its job.

Hope i cclarified the concept of Durable-Functions.

No comments:

Post a Comment