Exploring Azure Durable Functions, Logic App and long-running action

Imagine you want to involve some long running custom external step in you Logic Apps workflow – this could be for example some step that requires manual work. There are two obvious ways to do this:

  1. Using a webhook action
  2. Using polling

In this post I’ll explore the second option, where I’ll implement an Azure Durable Function that completes only when a request is sent to a specific URL thus simulating a manual step that might take several days to complete.

Implementing Azure Durable Function

Let’s create a simple durable function that waits until another function gets called via a HTTP trigger. To start, add a durable function to you Azure Functions project in Visual Studio.

image

Now you have three methods visible that come with the durable function template. I’ve replaced the methods with the following three.

The first method is the actual function that initiates the durable process. It is a HTTP triggered function that has DurableOrchestrationClient starter object injected. 

image

The method utilizes the starter object to

  1. start a new durable function, called DuraDemo1, and
  2. return HTTP 202 response via call to CreateCheckStatusResponse method.

The second line of the function body means, that whenever a HTTP GET/POST is received, a HTTP 202 response is sent back with Location header information indicating the URL which the caller can use to poll the status of the function execution.

image

For example Logic Apps and Flow know how to use this kind response – they will poll the Location URL until HTTP 200 OK is received.

The second method displayed below, is the one that the previous method initiated with the starter.StartNewAsync method. (This method is not called directly by clients)

image

The method is injected with the DurableOrchestrationContext object. The first line of the method body initiates a task to wait for an external event within the given orchestration context by calling WaitForExternalEvent template method. The first and only argument to the method is the event name that is waited for.

As you might guess, the third method is the one that fires the DuraDemoEvent event:

image

The method takes the durable function instance id as a route parameter. That instance id is used by the DurableOrchestrationClient object’s RaiseEventAsync method so that the runtime knows into which durable orchestration context to send the event to.

The above method would be called when the imaginary manual process completes (via a button click, for example). After the event is handled, the next polling call to the Location URL discussed earlier returns HTTP 200 OK like below.

image

Calling the long running process from Logic App workflow

The last part of this blog post is very straight forward. I created a simple Logic App workflow that makes a HTTP request to my DuraDemo1_HttpStart function (the function that returns 202 response and Location URL in the header). 

When I run the workflow, the execution is stuck in the HTTP action – hence it is working as expected. Below I’ve waited for approximately seven minutes. 

image

Now it’s time to call the DuraDemo1_SendEvent function so the workflow is allowed to continue. To do this, I need to find the durable orchestration context id from somewhere. 

The context id can be found from the storage account that is attached to the function runtime. So I open up my storage explorer and browse to correct storage account and open up Tables. There you have two tables related to the durable functions context:

image

The one we’re interested in is DurableFunctionsHubInstances. It contains a row for each durable context, including the one that my Logic App workflow just started by calling the DuraDemo1_HttpStart function. 

image

PartitionKey is the value we want. So, finally, I make a call 

DuraDemo1_SendEvent passing the PartitionKey (= context id) to it. And voilá, the workflow finishes!

image

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s