Calling long running Azure functions from logic apps

Logic apps and Azure functions are best suited for serverless architecture, but, if you have requirement of long-running jobs, let say up to 10minutes, it is acceptable for Azure functions. This is because, functions can run for 10 minutes, but logic app waits only for 2 minutes for HTTP requests. If logic app doesn’t get any response within 2 minutes, the request will timeout and retries again (number of retries can be configured from logic app). This will never go to next step.

This can be solved with 2 approaches:

  1. Webhook with queue messaging
  2. Durable Azure functions (this is stable V2 Azure functions)

In this article, I will be explaining the 1st approach.

How it works:

  • The HTTP trigger Azure function will be called from logic app with a callback URL. (with webhook action)
  • HTTP trigger function will drop a message in the queue and returns the response to the logic app. Now, logic app thinks that the request is processing and waits until the callback URL is called.
  • As soon as a message is added in the queue, the queue trigger Azure function will be triggered. It will do the long running job and sends a response to the logic app. Once logic app gets a response, it will go to the next step.

How can this be achieved?

Step1:

Create a logic app and HTTP trigger Azure function and call the HTTP trigger function from logic app using webhook action. See the image below:

 

Step 2:

Configure the HTTP trigger Azure function output queue item. (function-> integrate->outputs)

Now drop a message in the queue which can be read in the “queue trigger Azure function”, find the below sample code.


using System.Net;
using System;
public static async Task<HttpResponseMessage>
Run(HttpRequestMessage req, TraceWriter log,ICollector<ProcessRequest> outputQueueItem)
{
       // Get request body
         dynamic data = await req.Content.ReadAsAsync<object>();
         log.Info("data is "+data);
         
        TestObj testData = new TestObj {
                Title = data.Title,
                Description = data.Description
        };
        string callbackUrl = data?.callbackUrl;
        log.Info("Call back url"+callbackUrl);
    
 outputQueueItem.Add(new ProcessRequest { callbackUrl = callbackUrl, TestData = testData });
    return req.CreateResponse(HttpStatusCode.OK, "test request received");
}
public class ProcessRequest
    {
        public string callbackUrl { get; set; }
        public TestObj TestData { get; set; }
    }
    public class TestObj { 
        public string Title { set; get; }
        public string Description { get; set; }
    }

———————————————————————————————————————————-

Step 3:

Configure the “queue trigger azure function” trigger,(function->integrate->triggers)

Sample code for queue trigger:

#r "Newtonsoft.Json.dll"
using System.Net.Http;
using System.Text;
using Newtonsoft.Json;
using System.Net;
using System.Web.Http;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

public static void Run([QueueTrigger("siteprovqueue")]ProcessRequest item, TraceWriter log)
{
    log.Info($"C# Queue trigger function processed: {item}");
    
    try{
            //Thread.Sleep(TimeSpan.FromMinutes(3));
            // your functionality goes here
        ProcessResponse response = new ProcessResponse() { Test = “Test” }
        string json = JsonConvert.SerializeObject(response);
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(item.callbackUrl);
        req.Method = "POST";
        req.ContentType = "application/json";				
        Stream stream = req.GetRequestStream();
        byte[] buffer = Encoding.UTF8.GetBytes(json);
        stream.Write(buffer,0, buffer.Length);
        HttpWebResponse res = (HttpWebResponse)req.GetResponse();
    }
catch(Exception ex){
    // log.Info(ex.Message);
    // log.Info(ex.InnerException.Message);
    }
}
    public class ProcessResponse
    {
        public string siteUrl { get; set; }
    }

 

Jeevan

Related posts

Challenges bring the best out of us. What about you?

We love what we do so much and we're always looking for the next big challenge, the next problem to be solved, the next idea that simply needs the breath of life to become a reality. What's your challenge?