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; }
    }

 

Related posts